michael@0: /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- michael@0: * michael@0: * This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: #ifndef nsWebBrowserPersist_h__ michael@0: #define nsWebBrowserPersist_h__ michael@0: michael@0: #include "nsCOMPtr.h" michael@0: #include "nsWeakReference.h" michael@0: michael@0: #include "nsIInterfaceRequestor.h" michael@0: #include "nsIMIMEService.h" michael@0: #include "nsIStreamListener.h" michael@0: #include "nsIOutputStream.h" michael@0: #include "nsIInputStream.h" michael@0: #include "nsIChannel.h" michael@0: #include "nsIStyleSheet.h" michael@0: #include "nsIDocumentEncoder.h" michael@0: #include "nsITransport.h" michael@0: #include "nsIProgressEventSink.h" michael@0: #include "nsIFile.h" michael@0: #include "nsIWebProgressListener2.h" michael@0: michael@0: #include "nsClassHashtable.h" michael@0: #include "nsHashKeys.h" michael@0: #include "nsTArray.h" michael@0: michael@0: #include "nsCWebBrowserPersist.h" michael@0: michael@0: class nsEncoderNodeFixup; michael@0: class nsIStorageStream; michael@0: michael@0: struct CleanupData; michael@0: struct DocData; michael@0: struct OutputData; michael@0: struct UploadData; michael@0: struct URIData; michael@0: michael@0: class nsWebBrowserPersist : public nsIInterfaceRequestor, michael@0: public nsIWebBrowserPersist, michael@0: public nsIStreamListener, michael@0: public nsIProgressEventSink, michael@0: public nsSupportsWeakReference michael@0: { michael@0: friend class nsEncoderNodeFixup; michael@0: michael@0: // Public members michael@0: public: michael@0: nsWebBrowserPersist(); michael@0: michael@0: NS_DECL_ISUPPORTS michael@0: NS_DECL_NSIINTERFACEREQUESTOR michael@0: NS_DECL_NSICANCELABLE michael@0: NS_DECL_NSIWEBBROWSERPERSIST michael@0: NS_DECL_NSIREQUESTOBSERVER michael@0: NS_DECL_NSISTREAMLISTENER michael@0: NS_DECL_NSIPROGRESSEVENTSINK michael@0: michael@0: // Protected members michael@0: protected: michael@0: virtual ~nsWebBrowserPersist(); michael@0: nsresult CloneNodeWithFixedUpAttributes( michael@0: nsIDOMNode *aNodeIn, bool *aSerializeCloneKids, nsIDOMNode **aNodeOut); michael@0: nsresult SaveURIInternal( michael@0: nsIURI *aURI, nsISupports *aCacheKey, nsIURI *aReferrer, michael@0: nsIInputStream *aPostData, const char *aExtraHeaders, nsIURI *aFile, michael@0: bool aCalcFileExt, bool aIsPrivate); michael@0: nsresult SaveChannelInternal( michael@0: nsIChannel *aChannel, nsIURI *aFile, bool aCalcFileExt); michael@0: nsresult SaveDocumentInternal( michael@0: nsIDOMDocument *aDocument, nsIURI *aFile, nsIURI *aDataPath); michael@0: nsresult SaveDocuments(); michael@0: nsresult GetDocEncoderContentType( michael@0: nsIDOMDocument *aDocument, const char16_t *aContentType, michael@0: char16_t **aRealContentType); michael@0: nsresult GetExtensionForContentType( michael@0: const char16_t *aContentType, char16_t **aExt); michael@0: nsresult GetDocumentExtension(nsIDOMDocument *aDocument, char16_t **aExt); michael@0: michael@0: // Private members michael@0: private: michael@0: void Cleanup(); michael@0: void CleanupLocalFiles(); michael@0: nsresult GetValidURIFromObject(nsISupports *aObject, nsIURI **aURI) const; michael@0: nsresult GetLocalFileFromURI(nsIURI *aURI, nsIFile **aLocalFile) const; michael@0: nsresult AppendPathToURI(nsIURI *aURI, const nsAString & aPath) const; michael@0: nsresult MakeAndStoreLocalFilenameInURIMap( michael@0: nsIURI *aURI, bool aNeedsPersisting, URIData **aData); michael@0: nsresult MakeOutputStream( michael@0: nsIURI *aFile, nsIOutputStream **aOutputStream); michael@0: nsresult MakeOutputStreamFromFile( michael@0: nsIFile *aFile, nsIOutputStream **aOutputStream); michael@0: nsresult MakeOutputStreamFromURI(nsIURI *aURI, nsIOutputStream **aOutStream); michael@0: nsresult CreateChannelFromURI(nsIURI *aURI, nsIChannel **aChannel); michael@0: nsresult StartUpload(nsIStorageStream *aOutStream, nsIURI *aDestinationURI, michael@0: const nsACString &aContentType); michael@0: nsresult StartUpload(nsIInputStream *aInputStream, nsIURI *aDestinationURI, michael@0: const nsACString &aContentType); michael@0: nsresult CalculateAndAppendFileExt(nsIURI *aURI, nsIChannel *aChannel, michael@0: nsIURI *aOriginalURIWithExtension); michael@0: nsresult CalculateUniqueFilename(nsIURI *aURI); michael@0: nsresult MakeFilenameFromURI( michael@0: nsIURI *aURI, nsString &aFilename); michael@0: nsresult StoreURI( michael@0: const char *aURI, michael@0: bool aNeedsPersisting = true, michael@0: URIData **aData = nullptr); michael@0: nsresult StoreURI( michael@0: nsIURI *aURI, michael@0: bool aNeedsPersisting = true, michael@0: URIData **aData = nullptr); michael@0: nsresult StoreURIAttributeNS( michael@0: nsIDOMNode *aNode, const char *aNamespaceURI, const char *aAttribute, michael@0: bool aNeedsPersisting = true, michael@0: URIData **aData = nullptr); michael@0: nsresult StoreURIAttribute( michael@0: nsIDOMNode *aNode, const char *aAttribute, michael@0: bool aNeedsPersisting = true, michael@0: URIData **aData = nullptr) michael@0: { michael@0: return StoreURIAttributeNS(aNode, "", aAttribute, aNeedsPersisting, aData); michael@0: } michael@0: bool DocumentEncoderExists(const char16_t *aContentType); michael@0: michael@0: nsresult GetNodeToFixup(nsIDOMNode *aNodeIn, nsIDOMNode **aNodeOut); michael@0: nsresult FixupURI(nsAString &aURI); michael@0: nsresult FixupNodeAttributeNS(nsIDOMNode *aNode, const char *aNamespaceURI, const char *aAttribute); michael@0: nsresult FixupNodeAttribute(nsIDOMNode *aNode, const char *aAttribute) michael@0: { michael@0: return FixupNodeAttributeNS(aNode, "", aAttribute); michael@0: } michael@0: nsresult FixupAnchor(nsIDOMNode *aNode); michael@0: nsresult FixupXMLStyleSheetLink(nsIDOMProcessingInstruction *aPI, const nsAString &aHref); michael@0: nsresult GetXMLStyleSheetLink(nsIDOMProcessingInstruction *aPI, nsAString &aHref); michael@0: michael@0: nsresult StoreAndFixupStyleSheet(nsIStyleSheet *aStyleSheet); michael@0: nsresult SaveDocumentWithFixup( michael@0: nsIDOMDocument *pDocument, nsIDocumentEncoderNodeFixup *pFixup, michael@0: nsIURI *aFile, bool aReplaceExisting, const nsACString &aFormatType, michael@0: const nsCString &aSaveCharset, uint32_t aFlags); michael@0: nsresult SaveSubframeContent( michael@0: nsIDOMDocument *aFrameContent, URIData *aData); michael@0: nsresult SetDocumentBase(nsIDOMDocument *aDocument, nsIURI *aBaseURI); michael@0: nsresult SendErrorStatusChange( michael@0: bool aIsReadError, nsresult aResult, nsIRequest *aRequest, nsIURI *aURI); michael@0: nsresult OnWalkDOMNode(nsIDOMNode *aNode); michael@0: michael@0: nsresult FixRedirectedChannelEntry(nsIChannel *aNewChannel); michael@0: michael@0: void EndDownload(nsresult aResult = NS_OK); michael@0: nsresult SaveGatheredURIs(nsIURI *aFileAsURI); michael@0: bool SerializeNextFile(); michael@0: void CalcTotalProgress(); michael@0: michael@0: void SetApplyConversionIfNeeded(nsIChannel *aChannel); michael@0: michael@0: // Hash table enumerators michael@0: static PLDHashOperator EnumPersistURIs( michael@0: const nsACString &aKey, URIData *aData, void* aClosure); michael@0: static PLDHashOperator EnumCleanupOutputMap( michael@0: nsISupports *aKey, OutputData *aData, void* aClosure); michael@0: static PLDHashOperator EnumCleanupUploadList( michael@0: nsISupports *aKey, UploadData *aData, void* aClosure); michael@0: static PLDHashOperator EnumCalcProgress( michael@0: nsISupports *aKey, OutputData *aData, void* aClosure); michael@0: static PLDHashOperator EnumCalcUploadProgress( michael@0: nsISupports *aKey, UploadData *aData, void* aClosure); michael@0: static PLDHashOperator EnumFixRedirect( michael@0: nsISupports *aKey, OutputData *aData, void* aClosure); michael@0: static PLDHashOperator EnumCountURIsToPersist( michael@0: const nsACString &aKey, URIData *aData, void* aClosure); michael@0: michael@0: nsCOMPtr mCurrentDataPath; michael@0: bool mCurrentDataPathIsRelative; michael@0: nsCString mCurrentRelativePathToData; michael@0: nsCOMPtr mCurrentBaseURI; michael@0: nsCString mCurrentCharset; michael@0: nsCOMPtr mTargetBaseURI; michael@0: uint32_t mCurrentThingsToPersist; michael@0: michael@0: nsCOMPtr mMIMEService; michael@0: nsCOMPtr mURI; michael@0: nsCOMPtr mProgressListener; michael@0: /** michael@0: * Progress listener for 64-bit values; this is the same object as michael@0: * mProgressListener, but is a member to avoid having to qi it for each michael@0: * progress notification. michael@0: */ michael@0: nsCOMPtr mProgressListener2; michael@0: nsCOMPtr mEventSink; michael@0: nsClassHashtable mOutputMap; michael@0: nsClassHashtable mUploadList; michael@0: nsClassHashtable mURIMap; michael@0: nsTArray mDocList; michael@0: nsTArray mCleanupList; michael@0: nsTArray mFilenameList; michael@0: bool mFirstAndOnlyUse; michael@0: bool mCancel; michael@0: bool mJustStartedLoading; michael@0: bool mCompleted; michael@0: bool mStartSaving; michael@0: bool mReplaceExisting; michael@0: bool mSerializingOutput; michael@0: bool mIsPrivate; michael@0: uint32_t mPersistFlags; michael@0: nsresult mPersistResult; michael@0: int64_t mTotalCurrentProgress; michael@0: int64_t mTotalMaxProgress; michael@0: int16_t mWrapColumn; michael@0: uint32_t mEncodingFlags; michael@0: nsString mContentType; michael@0: }; michael@0: michael@0: // Helper class does node fixup during persistence michael@0: class nsEncoderNodeFixup : public nsIDocumentEncoderNodeFixup michael@0: { michael@0: public: michael@0: nsEncoderNodeFixup(); michael@0: michael@0: NS_DECL_ISUPPORTS michael@0: NS_IMETHOD FixupNode(nsIDOMNode *aNode, bool *aSerializeCloneKids, nsIDOMNode **aOutNode); michael@0: michael@0: nsWebBrowserPersist *mWebBrowserPersist; michael@0: michael@0: protected: michael@0: virtual ~nsEncoderNodeFixup(); michael@0: }; michael@0: michael@0: #endif