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:
bzbarsky%mit.edu 2005-01-15 17:47:23 +00:00
Родитель 3e66dcd1f7
Коммит d185bdf1ce
9 изменённых файлов: 78 добавлений и 13 удалений

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

@ -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__ */