From fd1c7b2e6cd992b34d62fec7f13d68d69b577577 Mon Sep 17 00:00:00 2001 From: "shanjian%netscape.com" Date: Mon, 26 Aug 2002 20:13:31 +0000 Subject: [PATCH] #162239 POST document could not inherit charset from previous page if the previous charset is from autodetection. r=ftang, darin, sr=jst added PrevDocCharset to markupViewer, and pass around previous document charset. This charset is later used to load POST document. --- content/base/src/nsDocumentViewer.cpp | 26 ++++++++++++++ .../html/document/src/nsHTMLContentSink.cpp | 35 +++++++++++++++++++ content/html/document/src/nsHTMLDocument.cpp | 34 ++++++++++++------ docshell/base/nsDocShell.cpp | 6 ++++ docshell/base/nsIMarkupDocumentViewer.idl | 5 +++ htmlparser/public/nsIParser.h | 15 ++++---- intl/chardet/src/nsDetectionAdaptor.cpp | 5 +++ layout/base/nsDocumentViewer.cpp | 26 ++++++++++++++ parser/htmlparser/public/nsIParser.h | 15 ++++---- 9 files changed, 143 insertions(+), 24 deletions(-) diff --git a/content/base/src/nsDocumentViewer.cpp b/content/base/src/nsDocumentViewer.cpp index 985401919aa1..a60ed91bac48 100644 --- a/content/base/src/nsDocumentViewer.cpp +++ b/content/base/src/nsDocumentViewer.cpp @@ -467,6 +467,7 @@ protected: nsString mHintCharset; PRInt32 mHintCharsetSource; nsString mForceCharacterSet; + nsString mPrevDocCharacterSet; }; //------------------------------------------------------------------ @@ -2397,6 +2398,31 @@ NS_IMETHODIMP DocumentViewerImpl::GetHintCharacterSetSource(PRInt32 *aHintCharac return NS_OK; } + +NS_IMETHODIMP DocumentViewerImpl::GetPrevDocCharacterSet(PRUnichar * *aPrevDocCharacterSet) +{ + NS_ENSURE_ARG_POINTER(aPrevDocCharacterSet); + + *aPrevDocCharacterSet = ToNewUnicode(mPrevDocCharacterSet); + + return NS_OK; +} + +static void +SetChildPrevDocCharacterSet(nsIMarkupDocumentViewer* aChild, void* aClosure) +{ + aChild->SetPrevDocCharacterSet((PRUnichar*) aClosure); +} + + +NS_IMETHODIMP DocumentViewerImpl::SetPrevDocCharacterSet(const PRUnichar* aPrevDocCharacterSet) +{ + mPrevDocCharacterSet = aPrevDocCharacterSet; + return CallChildren(SetChildPrevDocCharacterSet, + (void*) aPrevDocCharacterSet); +} + + static void SetChildHintCharacterSetSource(nsIMarkupDocumentViewer* aChild, void* aClosure) { diff --git a/content/html/document/src/nsHTMLContentSink.cpp b/content/html/document/src/nsHTMLContentSink.cpp index 35afd4b2f181..5d95f414f8bc 100644 --- a/content/html/document/src/nsHTMLContentSink.cpp +++ b/content/html/document/src/nsHTMLContentSink.cpp @@ -151,6 +151,7 @@ #include "nsLayoutCID.h" #include "nsIFrameManager.h" #include "nsILayoutHistoryState.h" +#include "nsIDocShellTreeItem.h" #include "nsEscape.h" @@ -5117,6 +5118,40 @@ HTMLContentSink::FlushPendingNotifications() NS_IMETHODIMP HTMLContentSink::SetDocumentCharset(nsAString& aCharset) { + if (mWebShell) { + // the following logic to get muCV is copied from + // nsHTMLDocument::StartDocumentLoad + // We need to call muCV->SetPrevDocCharacterSet here in case + // the charset is detected by parser DetectMetaTag + nsCOMPtr docShell(do_QueryInterface(mWebShell)); + nsCOMPtr muCV; + nsCOMPtr cv; + docShell->GetContentViewer(getter_AddRefs(cv)); + if (cv) { + muCV = do_QueryInterface(cv); + } else { + // in this block of code, if we get an error result, we return it + // but if we get a null pointer, that's perfectly legal for parent and parentContentViewer + nsCOMPtr docShellAsItem(do_QueryInterface(docShell)); + NS_ENSURE_TRUE(docShellAsItem, NS_ERROR_FAILURE); + + nsCOMPtr parentAsItem; + docShellAsItem->GetSameTypeParent(getter_AddRefs(parentAsItem)); + + nsCOMPtr parent(do_QueryInterface(parentAsItem)); + if (parent) { + nsCOMPtr parentContentViewer; + nsresult rv = parent->GetContentViewer(getter_AddRefs(parentContentViewer)); + if (NS_SUCCEEDED(rv) && parentContentViewer) { + muCV = do_QueryInterface(parentContentViewer); + } + } + } + if (muCV) { + muCV->SetPrevDocCharacterSet(PromiseFlatString(aCharset).get()); + } + } + if (mDocument) { return mDocument->SetDocumentCharacterSet(aCharset); } diff --git a/content/html/document/src/nsHTMLDocument.cpp b/content/html/document/src/nsHTMLDocument.cpp index 54eea7bf7433..1f2b255981c2 100644 --- a/content/html/document/src/nsHTMLDocument.cpp +++ b/content/html/document/src/nsHTMLDocument.cpp @@ -964,17 +964,27 @@ nsHTMLDocument::StartDocumentLoad(const char* aCommand, UseWeakDocTypeDefault(charsetSource, charset); } } - - if(kCharsetFromAutoDetection > charsetSource) { + + PRBool isPostPage = PR_FALSE; + //check if current doc is from POST command + if (httpChannel) { nsCAutoString methodStr; - if (httpChannel) { - rv = httpChannel->GetRequestMethod(methodStr); - if (NS_FAILED(rv) || !methodStr.Equals(NS_LITERAL_CSTRING("POST"))) { - StartAutodetection(docShell, charset, aCommand); - } + rv = httpChannel->GetRequestMethod(methodStr); + if (NS_SUCCEEDED(rv) && methodStr.Equals(NS_LITERAL_CSTRING("POST"))) + isPostPage = PR_TRUE; + } + + if (isPostPage && muCV && kCharsetFromHintPrevDoc > charsetSource) { + PRUnichar* requestCharset; + muCV->GetPrevDocCharacterSet(&requestCharset); + if (*requestCharset) { + charsetSource = kCharsetFromHintPrevDoc; + charset = requestCharset; } - else - StartAutodetection(docShell, charset, aCommand); + } + + if(kCharsetFromAutoDetection > charsetSource && !isPostPage) { + StartAutodetection(docShell, charset, aCommand); } #endif @@ -987,7 +997,11 @@ nsHTMLDocument::StartDocumentLoad(const char* aCommand, SetDocumentCharacterSet(charset); SetDocumentCharacterSetSource(charsetSource); - + + // set doc charset to muCV for next document. + if (muCV) + muCV->SetPrevDocCharacterSet(charset.get()); + if(cacheDescriptor) { rv = cacheDescriptor->SetMetaDataElement("charset", NS_ConvertUCS2toUTF8(charset).get()); diff --git a/docshell/base/nsDocShell.cpp b/docshell/base/nsDocShell.cpp index 9075d3ccd8fc..71266be61a4d 100644 --- a/docshell/base/nsDocShell.cpp +++ b/docshell/base/nsDocShell.cpp @@ -4442,6 +4442,7 @@ nsDocShell::SetupNewViewer(nsIContentViewer * aNewViewer) nsXPIDLString forceCharset; nsXPIDLString hintCharset; PRInt32 hintCharsetSource; + nsXPIDLString prevDocCharset; nsCOMPtr newMUDV(do_QueryInterface(aNewViewer)); @@ -4459,6 +4460,9 @@ nsDocShell::SetupNewViewer(nsIContentViewer * aNewViewer) NS_ENSURE_SUCCESS(oldMUDV-> GetHintCharacterSetSource(&hintCharsetSource), NS_ERROR_FAILURE); + NS_ENSURE_SUCCESS(oldMUDV-> + GetPrevDocCharacterSet(getter_Copies(prevDocCharset)), + NS_ERROR_FAILURE); // set the old state onto the new content viewer NS_ENSURE_SUCCESS(newMUDV->SetDefaultCharacterSet(defaultCharset), @@ -4470,6 +4474,8 @@ nsDocShell::SetupNewViewer(nsIContentViewer * aNewViewer) NS_ENSURE_SUCCESS(newMUDV-> SetHintCharacterSetSource(hintCharsetSource), NS_ERROR_FAILURE); + NS_ENSURE_SUCCESS(newMUDV->SetPrevDocCharacterSet(prevDocCharset), + NS_ERROR_FAILURE); } } diff --git a/docshell/base/nsIMarkupDocumentViewer.idl b/docshell/base/nsIMarkupDocumentViewer.idl index c31542c08636..7c804d5ddefa 100644 --- a/docshell/base/nsIMarkupDocumentViewer.idl +++ b/docshell/base/nsIMarkupDocumentViewer.idl @@ -70,6 +70,11 @@ interface nsIMarkupDocumentViewer : nsISupports */ attribute PRInt32 hintCharacterSetSource; + /* + character set from prev document + */ + attribute wstring prevDocCharacterSet; + //void GetCharacterSetHint(in wstring hintCharset, in PRInt32 charsetSource); /** diff --git a/htmlparser/public/nsIParser.h b/htmlparser/public/nsIParser.h index d40dd5f55800..3ef4e1d9f7fb 100644 --- a/htmlparser/public/nsIParser.h +++ b/htmlparser/public/nsIParser.h @@ -102,13 +102,14 @@ enum eParserDocType { #define kCharsetFromParentFrame 5 #define kCharsetFromBookmarks 6 #define kCharsetFromAutoDetection 7 -#define kCharsetFromMetaTag 8 -#define kCharsetFromByteOrderMark 9 -#define kCharsetFromChannel 10 -#define kCharsetFromParentForced 11 -#define kCharsetFromUserForced 12 -#define kCharsetFromOtherComponent 13 -#define kCharsetFromPreviousLoading 14 +#define kCharsetFromHintPrevDoc 8 +#define kCharsetFromMetaTag 9 +#define kCharsetFromByteOrderMark 10 +#define kCharsetFromChannel 11 +#define kCharsetFromParentForced 12 +#define kCharsetFromUserForced 13 +#define kCharsetFromOtherComponent 14 +#define kCharsetFromPreviousLoading 15 enum eStreamState {eNone,eOnStart,eOnDataAvail,eOnStop}; diff --git a/intl/chardet/src/nsDetectionAdaptor.cpp b/intl/chardet/src/nsDetectionAdaptor.cpp index e609f7a8bda4..e926851a707f 100644 --- a/intl/chardet/src/nsDetectionAdaptor.cpp +++ b/intl/chardet/src/nsDetectionAdaptor.cpp @@ -44,6 +44,7 @@ #include "nsIParser.h" #include "nsIDocument.h" #include "nsDetectionAdaptor.h" +#include "nsIContentSink.h" static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID); @@ -65,6 +66,10 @@ NS_IMETHODIMP nsMyObserver::Notify( mWeakRefParser->GetDocumentCharset(existingCharset, existingSource); if (existingSource < kCharsetFromAutoDetection) { mWeakRefParser->SetDocumentCharset(newcharset, kCharsetFromAutoDetection); + nsCOMPtr contentSink = mWeakRefParser->GetContentSink(); + if (contentSink) + contentSink->SetDocumentCharset(newcharset); + if(mWeakRefDocument) mWeakRefDocument->SetDocumentCharacterSet(newcharset); } diff --git a/layout/base/nsDocumentViewer.cpp b/layout/base/nsDocumentViewer.cpp index 985401919aa1..a60ed91bac48 100644 --- a/layout/base/nsDocumentViewer.cpp +++ b/layout/base/nsDocumentViewer.cpp @@ -467,6 +467,7 @@ protected: nsString mHintCharset; PRInt32 mHintCharsetSource; nsString mForceCharacterSet; + nsString mPrevDocCharacterSet; }; //------------------------------------------------------------------ @@ -2397,6 +2398,31 @@ NS_IMETHODIMP DocumentViewerImpl::GetHintCharacterSetSource(PRInt32 *aHintCharac return NS_OK; } + +NS_IMETHODIMP DocumentViewerImpl::GetPrevDocCharacterSet(PRUnichar * *aPrevDocCharacterSet) +{ + NS_ENSURE_ARG_POINTER(aPrevDocCharacterSet); + + *aPrevDocCharacterSet = ToNewUnicode(mPrevDocCharacterSet); + + return NS_OK; +} + +static void +SetChildPrevDocCharacterSet(nsIMarkupDocumentViewer* aChild, void* aClosure) +{ + aChild->SetPrevDocCharacterSet((PRUnichar*) aClosure); +} + + +NS_IMETHODIMP DocumentViewerImpl::SetPrevDocCharacterSet(const PRUnichar* aPrevDocCharacterSet) +{ + mPrevDocCharacterSet = aPrevDocCharacterSet; + return CallChildren(SetChildPrevDocCharacterSet, + (void*) aPrevDocCharacterSet); +} + + static void SetChildHintCharacterSetSource(nsIMarkupDocumentViewer* aChild, void* aClosure) { diff --git a/parser/htmlparser/public/nsIParser.h b/parser/htmlparser/public/nsIParser.h index d40dd5f55800..3ef4e1d9f7fb 100644 --- a/parser/htmlparser/public/nsIParser.h +++ b/parser/htmlparser/public/nsIParser.h @@ -102,13 +102,14 @@ enum eParserDocType { #define kCharsetFromParentFrame 5 #define kCharsetFromBookmarks 6 #define kCharsetFromAutoDetection 7 -#define kCharsetFromMetaTag 8 -#define kCharsetFromByteOrderMark 9 -#define kCharsetFromChannel 10 -#define kCharsetFromParentForced 11 -#define kCharsetFromUserForced 12 -#define kCharsetFromOtherComponent 13 -#define kCharsetFromPreviousLoading 14 +#define kCharsetFromHintPrevDoc 8 +#define kCharsetFromMetaTag 9 +#define kCharsetFromByteOrderMark 10 +#define kCharsetFromChannel 11 +#define kCharsetFromParentForced 12 +#define kCharsetFromUserForced 13 +#define kCharsetFromOtherComponent 14 +#define kCharsetFromPreviousLoading 15 enum eStreamState {eNone,eOnStart,eOnDataAvail,eOnStop};