diff --git a/mozilla/content/base/public/nsContentUtils.h b/mozilla/content/base/public/nsContentUtils.h index 35f051118b7..27cc99550bf 100644 --- a/mozilla/content/base/public/nsContentUtils.h +++ b/mozilla/content/base/public/nsContentUtils.h @@ -267,6 +267,7 @@ public: } static nsresult GenerateStateKey(nsIContent* aContent, + nsIDocument* aDocument, nsIStatefulFrame::SpecialStateID aID, nsACString& aKey); diff --git a/mozilla/content/base/public/nsIDocument.h b/mozilla/content/base/public/nsIDocument.h index 2df3255ce89..c3de2d07ade 100644 --- a/mozilla/content/base/public/nsIDocument.h +++ b/mozilla/content/base/public/nsIDocument.h @@ -88,10 +88,10 @@ class nsHTMLStyleSheet; class nsIHTMLCSSStyleSheet; // IID for the nsIDocument interface -// c59c70e5-28d1-494b-9f8e-c18368d09ebc +// c76fbc2d-2dca-4ce1-b6e9-7f7030b01e17 #define NS_IDOCUMENT_IID \ -{ 0x9f670164, 0xc446, 0x11d8, \ - { 0x84, 0xe1, 0x00, 0x0a, 0x95, 0xdc, 0x23, 0x4c } } +{ 0xc76fbc2d, 0x2dca, 0x4ce1, \ + { 0xb6, 0xe9, 0x7f, 0x70, 0x30, 0xb0, 0x1e, 0x17 } } // The base value for the content ID counter. // This counter is used by the document to @@ -116,7 +116,8 @@ public: nsIDocument() : mCharacterSet(NS_LITERAL_CSTRING("ISO-8859-1")), mNextContentID(NS_CONTENT_ID_COUNTER_BASE), - mNodeInfoManager(nsnull) + mNodeInfoManager(nsnull), + mPartID(0) { } @@ -635,6 +636,20 @@ public: nsPropertyTable* PropertyTable() { return &mPropertyTable; } + /** + * Sets the ID used to identify this part of the multipart document + */ + void SetPartID(PRUint32 aID) { + mPartID = aID; + } + + /** + * Return the ID used to identify this part of the multipart document + */ + PRUint32 GetPartID() const { + return mPartID; + } + protected: ~nsIDocument() { @@ -680,6 +695,10 @@ protected: // The document's security info nsCOMPtr mSecurityInfo; + + // if this document is part of a multipart document, + // the ID can be used to distinguish it from the other parts. + PRUint32 mPartID; }; diff --git a/mozilla/content/base/src/nsContentUtils.cpp b/mozilla/content/base/src/nsContentUtils.cpp index d8079f4f647..406a218a36f 100644 --- a/mozilla/content/base/src/nsContentUtils.cpp +++ b/mozilla/content/base/src/nsContentUtils.cpp @@ -1387,14 +1387,18 @@ static inline PRBool IsAutocompleteOff(nsIDOMElement* aElement) /*static*/ nsresult nsContentUtils::GenerateStateKey(nsIContent* aContent, + nsIDocument* aDocument, nsIStatefulFrame::SpecialStateID aID, nsACString& aKey) { aKey.Truncate(); + PRUint32 partID = aDocument ? aDocument->GetPartID() : 0; + // SpecialStateID case - e.g. scrollbars around the content window // The key in this case is the special state id (always < min(contentID)) if (nsIStatefulFrame::eNoID != aID) { + KeyAppendInt(partID, aKey); // first append a partID KeyAppendInt(aID, aKey); return NS_OK; } @@ -1415,6 +1419,7 @@ nsContentUtils::GenerateStateKey(nsIContent* aContent, nsCOMPtr htmlDocument(do_QueryInterface(aContent->GetDocument())); + KeyAppendInt(partID, aKey); // first append a partID PRBool generatedUniqueKey = PR_FALSE; if (htmlDocument) { diff --git a/mozilla/content/html/content/src/nsGenericHTMLElement.cpp b/mozilla/content/html/content/src/nsGenericHTMLElement.cpp index 9f80ecddece..5bb19617f6b 100644 --- a/mozilla/content/html/content/src/nsGenericHTMLElement.cpp +++ b/mozilla/content/html/content/src/nsGenericHTMLElement.cpp @@ -2320,7 +2320,7 @@ nsGenericHTMLElement::GetLayoutHistoryAndKey(nsGenericHTMLElement* aContent, // // Get the state key // - rv = nsContentUtils::GenerateStateKey(aContent, nsIStatefulFrame::eNoID, aKey); + rv = nsContentUtils::GenerateStateKey(aContent, doc, nsIStatefulFrame::eNoID, aKey); NS_ENSURE_SUCCESS(rv, rv); // If the state key is blank, this is anonymous content or for diff --git a/mozilla/docshell/base/nsDocShell.cpp b/mozilla/docshell/base/nsDocShell.cpp index d43ba133c54..cf3f9d6be1c 100644 --- a/mozilla/docshell/base/nsDocShell.cpp +++ b/mozilla/docshell/base/nsDocShell.cpp @@ -4705,6 +4705,22 @@ nsDocShell::CreateContentViewer(const char *aContentType, mEODForCurrentDocument = PR_FALSE; + // if this document is part of a multipart document, + // the ID can be used to distinguish it from the other parts. + nsCOMPtr multiPartChannel(do_QueryInterface(request)); + if (multiPartChannel) { + nsCOMPtr shell; + rv = GetPresShell(getter_AddRefs(shell)); + if (NS_SUCCEEDED(rv) && shell) { + nsIDocument *doc = shell->GetDocument(); + if (doc) { + PRUint32 partID; + multiPartChannel->GetPartID(&partID); + doc->SetPartID(partID); + } + } + } + // Give hint to native plevent dispatch mechanism. If a document // is loading the native plevent dispatch mechanism should favor // performance over normal native event dispatch priorities. diff --git a/mozilla/layout/base/nsFrameManager.cpp b/mozilla/layout/base/nsFrameManager.cpp index e1ecac8c029..efe28eae489 100644 --- a/mozilla/layout/base/nsFrameManager.cpp +++ b/mozilla/layout/base/nsFrameManager.cpp @@ -1719,7 +1719,9 @@ nsFrameManager::CaptureFrameStateFor(nsIFrame* aFrame, // Generate the hash key to store the state under // Exit early if we get empty key nsCAutoString stateKey; - rv = nsContentUtils::GenerateStateKey(aFrame->GetContent(), aID, stateKey); + nsIContent* content = aFrame->GetContent(); + nsIDocument* doc = content ? content->GetCurrentDoc() : nsnull; + rv = nsContentUtils::GenerateStateKey(content, doc, aID, stateKey); if(NS_FAILED(rv) || stateKey.IsEmpty()) { return; } @@ -1779,7 +1781,8 @@ nsFrameManager::RestoreFrameStateFor(nsIFrame* aFrame, } nsCAutoString stateKey; - nsresult rv = nsContentUtils::GenerateStateKey(content, aID, stateKey); + nsIDocument* doc = content->GetCurrentDoc(); + nsresult rv = nsContentUtils::GenerateStateKey(content, doc, aID, stateKey); if (NS_FAILED(rv) || stateKey.IsEmpty()) { return; } diff --git a/mozilla/netwerk/base/public/nsIMultiPartChannel.idl b/mozilla/netwerk/base/public/nsIMultiPartChannel.idl index f6aac4ee26b..d8d58833a31 100644 --- a/mozilla/netwerk/base/public/nsIMultiPartChannel.idl +++ b/mozilla/netwerk/base/public/nsIMultiPartChannel.idl @@ -45,7 +45,7 @@ interface nsIChannel; * associated with a MultiPartChannel. */ -[scriptable, uuid(62d77f66-8ad0-4a7f-91a1-bb048b136490)] +[scriptable, uuid(c1284456-652d-4130-a1a4-48a652af2330)] interface nsIMultiPartChannel : nsISupports { /** @@ -59,4 +59,10 @@ interface nsIMultiPartChannel : nsISupports * handling method, preferred filename, etc. See RFC 2183. */ attribute ACString contentDisposition; + + /** + * Attribute guaranteed to be different for different parts of + * the same multipart document. + */ + readonly attribute PRUint32 partID; }; diff --git a/mozilla/netwerk/streamconv/converters/nsMultiMixedConv.cpp b/mozilla/netwerk/streamconv/converters/nsMultiMixedConv.cpp index 87d76ecc862..0ddfe65aff6 100644 --- a/mozilla/netwerk/streamconv/converters/nsMultiMixedConv.cpp +++ b/mozilla/netwerk/streamconv/converters/nsMultiMixedConv.cpp @@ -79,7 +79,7 @@ class nsPartChannel : public nsIChannel, public nsIMultiPartChannel { public: - nsPartChannel(nsIChannel *aMultipartChannel); + nsPartChannel(nsIChannel *aMultipartChannel, PRUint32 aPartID); void InitializeByteRange(PRInt64 aStart, PRInt64 aEnd); @@ -108,14 +108,18 @@ protected: PRBool mIsByteRangeRequest; nsInt64 mByteRangeStart; nsInt64 mByteRangeEnd; + + PRUint32 mPartID; // unique ID that can be used to identify + // this part of the multipart document }; -nsPartChannel::nsPartChannel(nsIChannel *aMultipartChannel) : +nsPartChannel::nsPartChannel(nsIChannel *aMultipartChannel, PRUint32 aPartID) : mStatus(NS_OK), mContentLength(LL_MAXUINT), mIsByteRangeRequest(PR_FALSE), mByteRangeStart(0), - mByteRangeEnd(0) + mByteRangeEnd(0), + mPartID(aPartID) { mMultipartChannel = aMultipartChannel; @@ -367,6 +371,13 @@ nsPartChannel::SetContentDisposition(const nsACString &aContentDisposition) return NS_OK; } +NS_IMETHODIMP +nsPartChannel::GetPartID(PRUint32 *aPartID) +{ + *aPartID = mPartID; + return NS_OK; +} + // // nsIByteRangeRequest implementation... // @@ -717,7 +728,9 @@ nsMultiMixedConv::OnStopRequest(nsIRequest *request, nsISupports *ctxt, // nsMultiMixedConv methods -nsMultiMixedConv::nsMultiMixedConv() { +nsMultiMixedConv::nsMultiMixedConv() : + mCurrentPartID(0) +{ mTokenLen = 0; mNewPart = PR_TRUE; mContentLength = LL_MAXUINT; @@ -764,7 +777,7 @@ nsMultiMixedConv::SendStart(nsIChannel *aChannel) { NS_ASSERTION(!mPartChannel, "tisk tisk, shouldn't be overwriting a channel"); nsPartChannel *newChannel; - newChannel = new nsPartChannel(aChannel); + newChannel = new nsPartChannel(aChannel, mCurrentPartID++); if (!newChannel) return NS_ERROR_OUT_OF_MEMORY; diff --git a/mozilla/netwerk/streamconv/converters/nsMultiMixedConv.h b/mozilla/netwerk/streamconv/converters/nsMultiMixedConv.h index a9525a30b5f..ab698d5b81c 100644 --- a/mozilla/netwerk/streamconv/converters/nsMultiMixedConv.h +++ b/mozilla/netwerk/streamconv/converters/nsMultiMixedConv.h @@ -137,6 +137,8 @@ protected: nsInt64 mByteRangeStart; nsInt64 mByteRangeEnd; PRBool mIsByteRangeRequest; + + PRUint32 mCurrentPartID; }; #endif /* __nsmultimixedconv__h__ */