From 1ddf9f13071c95472ade6566e36be9b380b6e3ef Mon Sep 17 00:00:00 2001 From: "harishd%netscape.com" Date: Sun, 14 May 2000 19:24:59 +0000 Subject: [PATCH] Fix for bugs: 34351 ( nsbeta2+ ) - Made webshell service available to observer base through parser bundle. 37503,36852 ( nsbeta2+ ) - Fixed crash in Observer base... ( caused by a wrong assumtion for document key ). The key now is always nsISupports*. 24474 - Fixed content leakage in my.netscape.com caused by a script entity in LAYER. 31890 - Mlk fix ( patch provided by Patrick ) ( r=me ) r= nisheeth git-svn-id: svn://10.0.0.236/trunk@69671 18797224-902f-48f8-a5cc-f745e15eee43 --- mozilla/htmlparser/src/CNavDTD.cpp | 9 +- mozilla/htmlparser/src/CParserContext.cpp | 1 + mozilla/htmlparser/src/nsDTDUtils.cpp | 3 +- mozilla/htmlparser/src/nsElementTable.cpp | 2 +- mozilla/htmlparser/src/nsHTMLTokens.cpp | 14 +- mozilla/htmlparser/src/nsIParser.h | 11 ++ mozilla/htmlparser/src/nsParser.cpp | 130 +++++++++++++++++- mozilla/htmlparser/src/nsParser.h | 49 ++++++- mozilla/parser/htmlparser/src/CNavDTD.cpp | 9 +- .../parser/htmlparser/src/CParserContext.cpp | 1 + mozilla/parser/htmlparser/src/nsDTDUtils.cpp | 3 +- .../parser/htmlparser/src/nsElementTable.cpp | 2 +- .../parser/htmlparser/src/nsHTMLTokens.cpp | 14 +- mozilla/parser/htmlparser/src/nsIParser.h | 11 ++ mozilla/parser/htmlparser/src/nsParser.cpp | 130 +++++++++++++++++- mozilla/parser/htmlparser/src/nsParser.h | 49 ++++++- 16 files changed, 404 insertions(+), 34 deletions(-) diff --git a/mozilla/htmlparser/src/CNavDTD.cpp b/mozilla/htmlparser/src/CNavDTD.cpp index 43e75daeed1..4515ee75fc9 100644 --- a/mozilla/htmlparser/src/CNavDTD.cpp +++ b/mozilla/htmlparser/src/CNavDTD.cpp @@ -1091,8 +1091,10 @@ nsresult CNavDTD::WillHandleStartTag(CToken* aToken,eHTMLTags aTag,nsCParserNode if(theService) { CParserContext* pc=mParser->PeekContext(); void* theDocID=(pc)? pc->mKey:0; + + const nsISupportsParserBundle* bundle=mParser->GetParserBundle(); - result=theService->Notify(aTag,aNode,theDocID, NS_ConvertToString(kHTMLTextContentType), mParser); + result=theService->Notify(aTag,aNode,(void*)bundle, NS_ConvertToString(kHTMLTextContentType), mParser); } } @@ -1426,7 +1428,6 @@ nsresult CNavDTD::HandleStartToken(CToken* aToken) { break; case eHTMLTag_noframes: - case eHTMLTag_nolayer: case eHTMLTag_noembed: mHasOpenNoXXX++; break; @@ -1666,7 +1667,6 @@ nsresult CNavDTD::HandleEndToken(CToken* aToken) { break; case eHTMLTag_noframes: - case eHTMLTag_nolayer: case eHTMLTag_noembed: case eHTMLTag_noscript: mHasOpenNoXXX--; @@ -1999,6 +1999,7 @@ nsresult CNavDTD::HandleDocTypeDeclToken(CToken* aToken){ MOZ_TIMER_DEBUGLOG(("Stop: Parse Time: CNavDTD::HandleDocTypeDeclToken(), this=%p\n", this)); result = (mSink)? mSink->AddDocTypeDecl(*theNode,mDTDMode):NS_OK; + mNodeRecycler->RecycleNode(theNode,mTokenRecycler); MOZ_TIMER_DEBUGLOG(("Start: Parse Time: CNavDTD::HandleDocTypeDeclToken(), this=%p\n", this)); @@ -3423,7 +3424,7 @@ nsresult CNavDTD::AddLeaf(const nsIParserNode *aNode){ nsresult CNavDTD::AddHeadLeaf(nsIParserNode *aNode){ nsresult result=NS_OK; - static eHTMLTags gNoXTags[]={eHTMLTag_noembed,eHTMLTag_noframes,eHTMLTag_nolayer,eHTMLTag_noscript}; + static eHTMLTags gNoXTags[]={eHTMLTag_noembed,eHTMLTag_noframes,eHTMLTag_noscript}; eHTMLTags theTag=(eHTMLTags)aNode->GetNodeType(); diff --git a/mozilla/htmlparser/src/CParserContext.cpp b/mozilla/htmlparser/src/CParserContext.cpp index 7162df20552..c5e7e5b81e2 100644 --- a/mozilla/htmlparser/src/CParserContext.cpp +++ b/mozilla/htmlparser/src/CParserContext.cpp @@ -115,6 +115,7 @@ CParserContext::~CParserContext(){ delete [] mTransferBuffer; NS_IF_RELEASE(mDTD); + NS_IF_RELEASE(mListener); //Remember that it's ok to simply ingore the PrevContext. diff --git a/mozilla/htmlparser/src/nsDTDUtils.cpp b/mozilla/htmlparser/src/nsDTDUtils.cpp index 55cd712a058..5edf6d7e436 100644 --- a/mozilla/htmlparser/src/nsDTDUtils.cpp +++ b/mozilla/htmlparser/src/nsDTDUtils.cpp @@ -844,7 +844,7 @@ CNodeRecycler::~CNodeRecycler() { nsCParserNode* theNode=0; #ifdef NS_DEBUG -#if 0 +#if 1 PRInt32 count=gNodeCount-mSharedNodes.GetSize(); if(count) { printf("%i of %i nodes leaked!\n",count,gNodeCount); @@ -1040,7 +1040,6 @@ void nsObserverTopic::RegisterObserverForTag(nsIElementObserver *anObserver,eHTM } } - /** * This method will notify observers registered for specific tags. * diff --git a/mozilla/htmlparser/src/nsElementTable.cpp b/mozilla/htmlparser/src/nsElementTable.cpp index c3ed69d12ea..bb8186056e1 100644 --- a/mozilla/htmlparser/src/nsElementTable.cpp +++ b/mozilla/htmlparser/src/nsElementTable.cpp @@ -850,7 +850,7 @@ void InitializeElementTable(void) { /*rootnodes,endrootnodes*/ &gRootTags,&gRootTags, /*autoclose starttags and endtags*/ 0,0,0,0, /*parent,incl,exclgroups*/ kBlock, kFlowEntity, kNone, - /*special props, prop-range*/ 0, kNoPropRange, + /*special props, prop-range*/ kRequiresBody, kNoPropRange, /*special parents,kids,skip*/ 0,0,eHTMLTag_unknown); Initialize( diff --git a/mozilla/htmlparser/src/nsHTMLTokens.cpp b/mozilla/htmlparser/src/nsHTMLTokens.cpp index 937632c3229..c1535882349 100644 --- a/mozilla/htmlparser/src/nsHTMLTokens.cpp +++ b/mozilla/htmlparser/src/nsHTMLTokens.cpp @@ -1357,7 +1357,7 @@ nsresult CAttributeToken::Consume(PRUnichar aChar, nsScanner& aScanner,PRInt32 a } else { //If you're here, handle an unquoted key. - static nsString theTerminals = NS_ConvertToString("\b\t\n\r \"<=>",9); + static nsString theTerminals = NS_ConvertToString("\b\t\n\r \"=>",8); result=aScanner.ReadUntil(mTextKey,theTerminals,PR_FALSE); } @@ -1391,6 +1391,18 @@ nsresult CAttributeToken::Consume(PRUnichar aChar, nsScanner& aScanner,PRInt32 a mHasEqualWithoutValue=PR_TRUE; result=aScanner.PutBack(aChar); } + else if(kAmpersand==aChar) { + // XXX - Discard script entity for now....except in + // view-source + PRBool discard=!aRetainWhitespace; + mTextValue.Append(aChar); + result=aScanner.GetChar(aChar); + if(NS_OK==result) { + mTextValue.Append(aChar); + result=CEntityToken::ConsumeEntity(aChar,mTextValue,aScanner); + } + if(discard) mTextValue.Truncate(); + } else { mTextValue.Append(aChar); //it's an alphanum attribute... result=ConsumeAttributeValueText(aChar,mTextValue,aScanner); diff --git a/mozilla/htmlparser/src/nsIParser.h b/mozilla/htmlparser/src/nsIParser.h index b4e8f413316..98048b3a770 100644 --- a/mozilla/htmlparser/src/nsIParser.h +++ b/mozilla/htmlparser/src/nsIParser.h @@ -38,12 +38,16 @@ #include "nsIStreamListener.h" #include "nsIDTD.h" #include "nsIInputStream.h" +#include "nsHashtable.h" #define NS_IPARSER_IID \ {0x355cbba0, 0xbf7d, 0x11d1, \ {0xaa, 0xd9, 0x00, 0x80, 0x5f, 0x8a, 0x3e, 0x14}} +// {8B6A98A0-260E-11d4-8153-0010A4E0C706} +#define NS_IPARSER_BUNDLE_IID \ +{ 0x8b6a98a0, 0x260e, 0x11d4, { 0x81, 0x53, 0x0, 0x10, 0xa4, 0xe0, 0xc7, 0x6 } }; class nsIContentSink; @@ -102,6 +106,13 @@ public: }; +class nsISupportsParserBundle : public nsISupports { +public: + static const nsIID& GetIID() { static nsIID iid = NS_IPARSER_BUNDLE_IID; return iid; } + NS_IMETHOD GetDataFromBundle(const nsString& aKey,nsISupports** anObject)=0; + NS_IMETHOD SetDataIntoBundle(const nsString& aKey,nsISupports* anObject)=0; +}; + /** * This class defines the iparser interface. This XPCOM * inteface is all that parser clients ever need to see. diff --git a/mozilla/htmlparser/src/nsParser.cpp b/mozilla/htmlparser/src/nsParser.cpp index a65b903e0c4..59828078936 100644 --- a/mozilla/htmlparser/src/nsParser.cpp +++ b/mozilla/htmlparser/src/nsParser.cpp @@ -44,7 +44,7 @@ #include "COtherDTD.h" #include "prenv.h" #include "nsParserCIID.h" - +#include "nsCOMPtr.h" //#define rickgdebug static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID); @@ -219,6 +219,7 @@ nsParser::nsParser(nsITokenObserver* anObserver) { mInternalState=NS_OK; mObserversEnabled=PR_TRUE; mCommand=eViewNormal; + mBundle=nsnull; MOZ_TIMER_DEBUGLOG(("Reset: Parse Time: nsParser::nsParser(), this=%p\n", this)); MOZ_TIMER_RESET(mParseTime); @@ -226,7 +227,6 @@ nsParser::nsParser(nsITokenObserver* anObserver) { MOZ_TIMER_RESET(mTokenizeTime); } - /** * Default destructor * @@ -239,6 +239,9 @@ nsParser::~nsParser() { NS_IF_RELEASE(mProgressEventSink); NS_IF_RELEASE(mSink); + if(mBundle) + delete mBundle; + //don't forget to add code here to delete //what may be several contexts... delete mParserContext; @@ -261,7 +264,7 @@ NS_IMPL_RELEASE(nsParser) * @return NS_xxx result code */ nsresult nsParser::QueryInterface(const nsIID& aIID, void** aInstancePtr) -{ +{ if (NULL == aInstancePtr) { return NS_ERROR_NULL_POINTER; } @@ -283,7 +286,10 @@ nsresult nsParser::QueryInterface(const nsIID& aIID, void** aInstancePtr) } else if(aIID.Equals(kClassIID)) { //do this class... *aInstancePtr = (nsParser*)(this); - } + } + else if(aIID.Equals(NS_GET_IID(nsISupportsParserBundle))) { + *aInstancePtr = (nsISupportsParserBundle*)(this); + } else { *aInstancePtr=0; return NS_NOINTERFACE; @@ -618,7 +624,7 @@ void DetermineParseMode(nsString& aBuffer,nsDTDMode& aParseMode,eParserDocType& } else { if(eDTDMode_unknown==aParseMode) { - aBuffer.InsertWithConversion("\n",0); + aBuffer.InsertWithConversion("\n",0); aDocType=eHTML3Text; aParseMode=eDTDMode_quirks; } @@ -2078,7 +2084,6 @@ nsParser::GetDTD(nsIDTD** aDTD) return NS_OK; } - /** * Get the observer service * @@ -2092,3 +2097,116 @@ CObserverService* nsParser::GetObserverService(void) { return 0; } +/** + * Store data into the bundle. + * + * @update harishd 05/10/00 + * @param aData - The data to be stored. + * @return NS_OK if all went well else ERROR. + */ +NS_IMETHODIMP +nsParser::SetDataIntoBundle(const nsString& aKey,nsISupports* anObject) { + nsresult result=NS_OK; + if(!mBundle) { + mBundle = new nsParserBundle(); + if(mBundle==nsnull) result=NS_ERROR_OUT_OF_MEMORY; + } + result=mBundle->SetDataIntoBundle(aKey,anObject); + return result; +} + +/** + * Retrieve data from the bundle by IID. + * NOTE: The object retireved should not be released + * + * @update harishd 05/10/00 + * @param aIID - The ID to identify the correct object in the bundle + * @return Return object if found in bundle else return NULL. + */ +NS_IMETHODIMP +nsParser::GetDataFromBundle(const nsString& aKey,nsISupports** anObject) { + nsresult result=NS_OK; + result=mBundle->GetDataFromBundle(aKey,anObject); + return result; +} + + +NS_IMPL_ISUPPORTS1(nsParserBundle, + nsISupportsParserBundle + ); + + +/** + * Release data from the Hash table + * + * @update harishd 05/10/00 + */ +static PRBool PR_CALLBACK ReleaseData(nsHashKey* aKey, void* aData, void* aClosure) { + nsISupports* object = (nsISupports*)aData; + NS_RELEASE(object); + return PR_TRUE; +} + +/** + * + * @update harishd 05/10/00 + */ +nsParserBundle::nsParserBundle (){ + mData=new nsHashtable(5); +} + +/** + * Release objects from the bundle. + * + * @update harishd 05/10/00 + */ +nsParserBundle::~nsParserBundle () { + mData->Enumerate(ReleaseData); + delete mData; +} + +/** + * Store data into the bundle. + * + * @update harishd 05/10/00 + * @param aData - The data to be stored. + * @return NS_OK if all went well else ERROR. + */ +NS_IMETHODIMP +nsParserBundle::SetDataIntoBundle(const nsString& aKey,nsISupports* anObject) { + nsresult result=NS_OK; + if(anObject) { + nsStringKey key(aKey); + PRBool found=mData->Exists(&key); + if(!found) { + NS_ADDREF(anObject); + mData->Put(&key,anObject); + } + } + return result; +} + +/** + * Retrieve data from the bundle by IID. + * NOTE: The object retrieved should not be released. + * + * @update harishd 05/10/00 + * @param aIID - The ID to identify the correct object in the bundle + * @return Return object if found in bundle else return NULL. + */ +NS_IMETHODIMP +nsParserBundle::GetDataFromBundle(const nsString& aKey,nsISupports** anObject) { + nsresult result=NS_OK; + + nsStringKey key(aKey); + *anObject=(mData)? (nsISupports*)mData->Get(&key):nsnull; + + if(*anObject) { + NS_ADDREF(*anObject); + } + else{ + result=NS_ERROR_NULL_POINTER; + } + + return result; +} diff --git a/mozilla/htmlparser/src/nsParser.h b/mozilla/htmlparser/src/nsParser.h index ec262291d48..c4b6d7bc701 100644 --- a/mozilla/htmlparser/src/nsParser.h +++ b/mozilla/htmlparser/src/nsParser.h @@ -75,7 +75,7 @@ class nsIDTD; class nsScanner; class nsIParserFilter; class nsIProgressEventSink; - +class nsParserBundle; #include @@ -84,11 +84,12 @@ class nsIProgressEventSink; #endif -CLASS_EXPORT_HTMLPARS nsParser : public nsIParser, public nsIStreamListener { +CLASS_EXPORT_HTMLPARS nsParser : public nsIParser, + public nsISupportsParserBundle, + public nsIStreamListener{ public: - friend class CTokenHandler; static void FreeSharedObjects(void); @@ -263,6 +264,8 @@ CLASS_EXPORT_HTMLPARS nsParser : public nsIParser, public nsIStreamListener { CParserContext* PopContext(); CParserContext* PeekContext() {return mParserContext;} + const nsParserBundle* GetParserBundle() { return mBundle; } + /** * * @update gess 1/22/99 @@ -295,6 +298,12 @@ CLASS_EXPORT_HTMLPARS nsParser : public nsIParser, public nsIStreamListener { */ CObserverService* GetObserverService(void); + + // nsISupportsParserBundle + NS_IMETHOD GetDataFromBundle(const nsString& aKey,nsISupports** anObject); + NS_IMETHOD SetDataIntoBundle(const nsString& aKey,nsISupports* anObject); + + protected: /** @@ -402,6 +411,8 @@ protected: CObserverService mObserverService; PRBool mObserversEnabled; nsString mCommandStr; + + nsParserBundle* mBundle; public: MOZ_TIMER_DECLARE(mParseTime) @@ -409,5 +420,37 @@ public: MOZ_TIMER_DECLARE(mTokenizeTime) }; +// ----------------------------------------------------------------- + +class nsParserBundle : public nsISupportsParserBundle { +public:; + + NS_DECL_ISUPPORTS + + nsParserBundle (); + ~nsParserBundle (); + + /** + * Retrieve data from the bundle by IID. + * + * @update harishd 05/10/00 + * @param aIID - The ID to identify the correct object in the bundle + * @return Return object if found in bundle else return NULL. + */ + NS_IMETHOD GetDataFromBundle(const nsString& aKey,nsISupports** anObject); + + /** + * Store data into the bundle. + * + * @update harishd 05/10/00 + * @param aData - The data to be stored. + * @return NS_OK if all went well else ERROR. + */ + NS_IMETHOD SetDataIntoBundle(const nsString& aKey,nsISupports* anObject); + +protected: + nsHashtable* mData; +}; + #endif diff --git a/mozilla/parser/htmlparser/src/CNavDTD.cpp b/mozilla/parser/htmlparser/src/CNavDTD.cpp index 43e75daeed1..4515ee75fc9 100644 --- a/mozilla/parser/htmlparser/src/CNavDTD.cpp +++ b/mozilla/parser/htmlparser/src/CNavDTD.cpp @@ -1091,8 +1091,10 @@ nsresult CNavDTD::WillHandleStartTag(CToken* aToken,eHTMLTags aTag,nsCParserNode if(theService) { CParserContext* pc=mParser->PeekContext(); void* theDocID=(pc)? pc->mKey:0; + + const nsISupportsParserBundle* bundle=mParser->GetParserBundle(); - result=theService->Notify(aTag,aNode,theDocID, NS_ConvertToString(kHTMLTextContentType), mParser); + result=theService->Notify(aTag,aNode,(void*)bundle, NS_ConvertToString(kHTMLTextContentType), mParser); } } @@ -1426,7 +1428,6 @@ nsresult CNavDTD::HandleStartToken(CToken* aToken) { break; case eHTMLTag_noframes: - case eHTMLTag_nolayer: case eHTMLTag_noembed: mHasOpenNoXXX++; break; @@ -1666,7 +1667,6 @@ nsresult CNavDTD::HandleEndToken(CToken* aToken) { break; case eHTMLTag_noframes: - case eHTMLTag_nolayer: case eHTMLTag_noembed: case eHTMLTag_noscript: mHasOpenNoXXX--; @@ -1999,6 +1999,7 @@ nsresult CNavDTD::HandleDocTypeDeclToken(CToken* aToken){ MOZ_TIMER_DEBUGLOG(("Stop: Parse Time: CNavDTD::HandleDocTypeDeclToken(), this=%p\n", this)); result = (mSink)? mSink->AddDocTypeDecl(*theNode,mDTDMode):NS_OK; + mNodeRecycler->RecycleNode(theNode,mTokenRecycler); MOZ_TIMER_DEBUGLOG(("Start: Parse Time: CNavDTD::HandleDocTypeDeclToken(), this=%p\n", this)); @@ -3423,7 +3424,7 @@ nsresult CNavDTD::AddLeaf(const nsIParserNode *aNode){ nsresult CNavDTD::AddHeadLeaf(nsIParserNode *aNode){ nsresult result=NS_OK; - static eHTMLTags gNoXTags[]={eHTMLTag_noembed,eHTMLTag_noframes,eHTMLTag_nolayer,eHTMLTag_noscript}; + static eHTMLTags gNoXTags[]={eHTMLTag_noembed,eHTMLTag_noframes,eHTMLTag_noscript}; eHTMLTags theTag=(eHTMLTags)aNode->GetNodeType(); diff --git a/mozilla/parser/htmlparser/src/CParserContext.cpp b/mozilla/parser/htmlparser/src/CParserContext.cpp index 7162df20552..c5e7e5b81e2 100644 --- a/mozilla/parser/htmlparser/src/CParserContext.cpp +++ b/mozilla/parser/htmlparser/src/CParserContext.cpp @@ -115,6 +115,7 @@ CParserContext::~CParserContext(){ delete [] mTransferBuffer; NS_IF_RELEASE(mDTD); + NS_IF_RELEASE(mListener); //Remember that it's ok to simply ingore the PrevContext. diff --git a/mozilla/parser/htmlparser/src/nsDTDUtils.cpp b/mozilla/parser/htmlparser/src/nsDTDUtils.cpp index 55cd712a058..5edf6d7e436 100644 --- a/mozilla/parser/htmlparser/src/nsDTDUtils.cpp +++ b/mozilla/parser/htmlparser/src/nsDTDUtils.cpp @@ -844,7 +844,7 @@ CNodeRecycler::~CNodeRecycler() { nsCParserNode* theNode=0; #ifdef NS_DEBUG -#if 0 +#if 1 PRInt32 count=gNodeCount-mSharedNodes.GetSize(); if(count) { printf("%i of %i nodes leaked!\n",count,gNodeCount); @@ -1040,7 +1040,6 @@ void nsObserverTopic::RegisterObserverForTag(nsIElementObserver *anObserver,eHTM } } - /** * This method will notify observers registered for specific tags. * diff --git a/mozilla/parser/htmlparser/src/nsElementTable.cpp b/mozilla/parser/htmlparser/src/nsElementTable.cpp index c3ed69d12ea..bb8186056e1 100644 --- a/mozilla/parser/htmlparser/src/nsElementTable.cpp +++ b/mozilla/parser/htmlparser/src/nsElementTable.cpp @@ -850,7 +850,7 @@ void InitializeElementTable(void) { /*rootnodes,endrootnodes*/ &gRootTags,&gRootTags, /*autoclose starttags and endtags*/ 0,0,0,0, /*parent,incl,exclgroups*/ kBlock, kFlowEntity, kNone, - /*special props, prop-range*/ 0, kNoPropRange, + /*special props, prop-range*/ kRequiresBody, kNoPropRange, /*special parents,kids,skip*/ 0,0,eHTMLTag_unknown); Initialize( diff --git a/mozilla/parser/htmlparser/src/nsHTMLTokens.cpp b/mozilla/parser/htmlparser/src/nsHTMLTokens.cpp index 937632c3229..c1535882349 100644 --- a/mozilla/parser/htmlparser/src/nsHTMLTokens.cpp +++ b/mozilla/parser/htmlparser/src/nsHTMLTokens.cpp @@ -1357,7 +1357,7 @@ nsresult CAttributeToken::Consume(PRUnichar aChar, nsScanner& aScanner,PRInt32 a } else { //If you're here, handle an unquoted key. - static nsString theTerminals = NS_ConvertToString("\b\t\n\r \"<=>",9); + static nsString theTerminals = NS_ConvertToString("\b\t\n\r \"=>",8); result=aScanner.ReadUntil(mTextKey,theTerminals,PR_FALSE); } @@ -1391,6 +1391,18 @@ nsresult CAttributeToken::Consume(PRUnichar aChar, nsScanner& aScanner,PRInt32 a mHasEqualWithoutValue=PR_TRUE; result=aScanner.PutBack(aChar); } + else if(kAmpersand==aChar) { + // XXX - Discard script entity for now....except in + // view-source + PRBool discard=!aRetainWhitespace; + mTextValue.Append(aChar); + result=aScanner.GetChar(aChar); + if(NS_OK==result) { + mTextValue.Append(aChar); + result=CEntityToken::ConsumeEntity(aChar,mTextValue,aScanner); + } + if(discard) mTextValue.Truncate(); + } else { mTextValue.Append(aChar); //it's an alphanum attribute... result=ConsumeAttributeValueText(aChar,mTextValue,aScanner); diff --git a/mozilla/parser/htmlparser/src/nsIParser.h b/mozilla/parser/htmlparser/src/nsIParser.h index b4e8f413316..98048b3a770 100644 --- a/mozilla/parser/htmlparser/src/nsIParser.h +++ b/mozilla/parser/htmlparser/src/nsIParser.h @@ -38,12 +38,16 @@ #include "nsIStreamListener.h" #include "nsIDTD.h" #include "nsIInputStream.h" +#include "nsHashtable.h" #define NS_IPARSER_IID \ {0x355cbba0, 0xbf7d, 0x11d1, \ {0xaa, 0xd9, 0x00, 0x80, 0x5f, 0x8a, 0x3e, 0x14}} +// {8B6A98A0-260E-11d4-8153-0010A4E0C706} +#define NS_IPARSER_BUNDLE_IID \ +{ 0x8b6a98a0, 0x260e, 0x11d4, { 0x81, 0x53, 0x0, 0x10, 0xa4, 0xe0, 0xc7, 0x6 } }; class nsIContentSink; @@ -102,6 +106,13 @@ public: }; +class nsISupportsParserBundle : public nsISupports { +public: + static const nsIID& GetIID() { static nsIID iid = NS_IPARSER_BUNDLE_IID; return iid; } + NS_IMETHOD GetDataFromBundle(const nsString& aKey,nsISupports** anObject)=0; + NS_IMETHOD SetDataIntoBundle(const nsString& aKey,nsISupports* anObject)=0; +}; + /** * This class defines the iparser interface. This XPCOM * inteface is all that parser clients ever need to see. diff --git a/mozilla/parser/htmlparser/src/nsParser.cpp b/mozilla/parser/htmlparser/src/nsParser.cpp index a65b903e0c4..59828078936 100644 --- a/mozilla/parser/htmlparser/src/nsParser.cpp +++ b/mozilla/parser/htmlparser/src/nsParser.cpp @@ -44,7 +44,7 @@ #include "COtherDTD.h" #include "prenv.h" #include "nsParserCIID.h" - +#include "nsCOMPtr.h" //#define rickgdebug static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID); @@ -219,6 +219,7 @@ nsParser::nsParser(nsITokenObserver* anObserver) { mInternalState=NS_OK; mObserversEnabled=PR_TRUE; mCommand=eViewNormal; + mBundle=nsnull; MOZ_TIMER_DEBUGLOG(("Reset: Parse Time: nsParser::nsParser(), this=%p\n", this)); MOZ_TIMER_RESET(mParseTime); @@ -226,7 +227,6 @@ nsParser::nsParser(nsITokenObserver* anObserver) { MOZ_TIMER_RESET(mTokenizeTime); } - /** * Default destructor * @@ -239,6 +239,9 @@ nsParser::~nsParser() { NS_IF_RELEASE(mProgressEventSink); NS_IF_RELEASE(mSink); + if(mBundle) + delete mBundle; + //don't forget to add code here to delete //what may be several contexts... delete mParserContext; @@ -261,7 +264,7 @@ NS_IMPL_RELEASE(nsParser) * @return NS_xxx result code */ nsresult nsParser::QueryInterface(const nsIID& aIID, void** aInstancePtr) -{ +{ if (NULL == aInstancePtr) { return NS_ERROR_NULL_POINTER; } @@ -283,7 +286,10 @@ nsresult nsParser::QueryInterface(const nsIID& aIID, void** aInstancePtr) } else if(aIID.Equals(kClassIID)) { //do this class... *aInstancePtr = (nsParser*)(this); - } + } + else if(aIID.Equals(NS_GET_IID(nsISupportsParserBundle))) { + *aInstancePtr = (nsISupportsParserBundle*)(this); + } else { *aInstancePtr=0; return NS_NOINTERFACE; @@ -618,7 +624,7 @@ void DetermineParseMode(nsString& aBuffer,nsDTDMode& aParseMode,eParserDocType& } else { if(eDTDMode_unknown==aParseMode) { - aBuffer.InsertWithConversion("\n",0); + aBuffer.InsertWithConversion("\n",0); aDocType=eHTML3Text; aParseMode=eDTDMode_quirks; } @@ -2078,7 +2084,6 @@ nsParser::GetDTD(nsIDTD** aDTD) return NS_OK; } - /** * Get the observer service * @@ -2092,3 +2097,116 @@ CObserverService* nsParser::GetObserverService(void) { return 0; } +/** + * Store data into the bundle. + * + * @update harishd 05/10/00 + * @param aData - The data to be stored. + * @return NS_OK if all went well else ERROR. + */ +NS_IMETHODIMP +nsParser::SetDataIntoBundle(const nsString& aKey,nsISupports* anObject) { + nsresult result=NS_OK; + if(!mBundle) { + mBundle = new nsParserBundle(); + if(mBundle==nsnull) result=NS_ERROR_OUT_OF_MEMORY; + } + result=mBundle->SetDataIntoBundle(aKey,anObject); + return result; +} + +/** + * Retrieve data from the bundle by IID. + * NOTE: The object retireved should not be released + * + * @update harishd 05/10/00 + * @param aIID - The ID to identify the correct object in the bundle + * @return Return object if found in bundle else return NULL. + */ +NS_IMETHODIMP +nsParser::GetDataFromBundle(const nsString& aKey,nsISupports** anObject) { + nsresult result=NS_OK; + result=mBundle->GetDataFromBundle(aKey,anObject); + return result; +} + + +NS_IMPL_ISUPPORTS1(nsParserBundle, + nsISupportsParserBundle + ); + + +/** + * Release data from the Hash table + * + * @update harishd 05/10/00 + */ +static PRBool PR_CALLBACK ReleaseData(nsHashKey* aKey, void* aData, void* aClosure) { + nsISupports* object = (nsISupports*)aData; + NS_RELEASE(object); + return PR_TRUE; +} + +/** + * + * @update harishd 05/10/00 + */ +nsParserBundle::nsParserBundle (){ + mData=new nsHashtable(5); +} + +/** + * Release objects from the bundle. + * + * @update harishd 05/10/00 + */ +nsParserBundle::~nsParserBundle () { + mData->Enumerate(ReleaseData); + delete mData; +} + +/** + * Store data into the bundle. + * + * @update harishd 05/10/00 + * @param aData - The data to be stored. + * @return NS_OK if all went well else ERROR. + */ +NS_IMETHODIMP +nsParserBundle::SetDataIntoBundle(const nsString& aKey,nsISupports* anObject) { + nsresult result=NS_OK; + if(anObject) { + nsStringKey key(aKey); + PRBool found=mData->Exists(&key); + if(!found) { + NS_ADDREF(anObject); + mData->Put(&key,anObject); + } + } + return result; +} + +/** + * Retrieve data from the bundle by IID. + * NOTE: The object retrieved should not be released. + * + * @update harishd 05/10/00 + * @param aIID - The ID to identify the correct object in the bundle + * @return Return object if found in bundle else return NULL. + */ +NS_IMETHODIMP +nsParserBundle::GetDataFromBundle(const nsString& aKey,nsISupports** anObject) { + nsresult result=NS_OK; + + nsStringKey key(aKey); + *anObject=(mData)? (nsISupports*)mData->Get(&key):nsnull; + + if(*anObject) { + NS_ADDREF(*anObject); + } + else{ + result=NS_ERROR_NULL_POINTER; + } + + return result; +} diff --git a/mozilla/parser/htmlparser/src/nsParser.h b/mozilla/parser/htmlparser/src/nsParser.h index ec262291d48..c4b6d7bc701 100644 --- a/mozilla/parser/htmlparser/src/nsParser.h +++ b/mozilla/parser/htmlparser/src/nsParser.h @@ -75,7 +75,7 @@ class nsIDTD; class nsScanner; class nsIParserFilter; class nsIProgressEventSink; - +class nsParserBundle; #include @@ -84,11 +84,12 @@ class nsIProgressEventSink; #endif -CLASS_EXPORT_HTMLPARS nsParser : public nsIParser, public nsIStreamListener { +CLASS_EXPORT_HTMLPARS nsParser : public nsIParser, + public nsISupportsParserBundle, + public nsIStreamListener{ public: - friend class CTokenHandler; static void FreeSharedObjects(void); @@ -263,6 +264,8 @@ CLASS_EXPORT_HTMLPARS nsParser : public nsIParser, public nsIStreamListener { CParserContext* PopContext(); CParserContext* PeekContext() {return mParserContext;} + const nsParserBundle* GetParserBundle() { return mBundle; } + /** * * @update gess 1/22/99 @@ -295,6 +298,12 @@ CLASS_EXPORT_HTMLPARS nsParser : public nsIParser, public nsIStreamListener { */ CObserverService* GetObserverService(void); + + // nsISupportsParserBundle + NS_IMETHOD GetDataFromBundle(const nsString& aKey,nsISupports** anObject); + NS_IMETHOD SetDataIntoBundle(const nsString& aKey,nsISupports* anObject); + + protected: /** @@ -402,6 +411,8 @@ protected: CObserverService mObserverService; PRBool mObserversEnabled; nsString mCommandStr; + + nsParserBundle* mBundle; public: MOZ_TIMER_DECLARE(mParseTime) @@ -409,5 +420,37 @@ public: MOZ_TIMER_DECLARE(mTokenizeTime) }; +// ----------------------------------------------------------------- + +class nsParserBundle : public nsISupportsParserBundle { +public:; + + NS_DECL_ISUPPORTS + + nsParserBundle (); + ~nsParserBundle (); + + /** + * Retrieve data from the bundle by IID. + * + * @update harishd 05/10/00 + * @param aIID - The ID to identify the correct object in the bundle + * @return Return object if found in bundle else return NULL. + */ + NS_IMETHOD GetDataFromBundle(const nsString& aKey,nsISupports** anObject); + + /** + * Store data into the bundle. + * + * @update harishd 05/10/00 + * @param aData - The data to be stored. + * @return NS_OK if all went well else ERROR. + */ + NS_IMETHOD SetDataIntoBundle(const nsString& aKey,nsISupports* anObject); + +protected: + nsHashtable* mData; +}; + #endif