зеркало из https://github.com/mozilla/pjs.git
Include the part number inside a multipart document in the state key, so that
state restoration works correctly on each part. Bug 47350, patch by Hideo Saito <saito@densan.co.jp>, r=bzbarsky, sr=js
This commit is contained in:
Родитель
3e66dcd1f7
Коммит
d185bdf1ce
|
@ -267,6 +267,7 @@ public:
|
|||
}
|
||||
|
||||
static nsresult GenerateStateKey(nsIContent* aContent,
|
||||
nsIDocument* aDocument,
|
||||
nsIStatefulFrame::SpecialStateID aID,
|
||||
nsACString& aKey);
|
||||
|
||||
|
|
|
@ -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<nsISupports> mSecurityInfo;
|
||||
|
||||
// if this document is part of a multipart document,
|
||||
// the ID can be used to distinguish it from the other parts.
|
||||
PRUint32 mPartID;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -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<nsIHTMLDocument> htmlDocument(do_QueryInterface(aContent->GetDocument()));
|
||||
|
||||
KeyAppendInt(partID, aKey); // first append a partID
|
||||
PRBool generatedUniqueKey = PR_FALSE;
|
||||
|
||||
if (htmlDocument) {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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<nsIMultiPartChannel> multiPartChannel(do_QueryInterface(request));
|
||||
if (multiPartChannel) {
|
||||
nsCOMPtr<nsIPresShell> 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.
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -137,6 +137,8 @@ protected:
|
|||
nsInt64 mByteRangeStart;
|
||||
nsInt64 mByteRangeEnd;
|
||||
PRBool mIsByteRangeRequest;
|
||||
|
||||
PRUint32 mCurrentPartID;
|
||||
};
|
||||
|
||||
#endif /* __nsmultimixedconv__h__ */
|
||||
|
|
Загрузка…
Ссылка в новой задаче