Added Observernotification for XML PI, cleaned up some warnings.

This commit is contained in:
harishd%netscape.com 1999-07-16 21:07:54 +00:00
Родитель cfb99ec34c
Коммит 9ddffbdebc
16 изменённых файлов: 298 добавлений и 198 удалений

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

@ -1034,39 +1034,7 @@ void WriteTokenToLog(CToken* aToken) {
aToken->DebugDumpSource(outputStream); //write token without close bracket...
}
#endif
/**************************************************************
Define the a functor used to notify observers...
**************************************************************/
class nsObserverNotifier: public nsDequeFunctor{
public:
nsObserverNotifier(eHTMLTags aTag,PRUint32 aCount,const PRUnichar** aKeys,
const PRUnichar** aValues,PRUint32 aUniqueKey){
mCount=aCount;
mKeys=aKeys;
mValues=aValues;
mUniqueKey=aUniqueKey;
mTag=aTag;
}
virtual void* operator()(void* anObject) {
nsIElementObserver* theObserver= (nsIElementObserver*)anObject;
if(theObserver) {
mResult = theObserver->Notify(mUniqueKey,mTag,mCount,mKeys,mValues);
}
if(NS_OK==mResult)
return 0;
return anObject;
}
const PRUnichar** mKeys;
const PRUnichar** mValues;
PRUint32 mCount;
PRUint32 mUniqueKey;
nsresult mResult;
eHTMLTags mTag;
};
/**
* This gets called before we've handled a given start tag.
* It's a generic hook to let us do pre processing.
@ -1084,53 +1052,45 @@ nsresult CNavDTD::WillHandleStartTag(CToken* aToken,eHTMLTags aTag,nsCParserNode
result=CollectSkippedContent(aNode,theAttrCount);
}
/**********************************************************
/**********************************************************
THIS WILL ULTIMATELY BECOME THE REAL OBSERVER API...
**********************************************************/
static CObserverDictionary gObserverDictionary;
if(aTag < NS_HTML_TAG_MAX){
nsDeque* theDeque=gObserverDictionary.GetObserversForTag(aTag);
if(theDeque){
PRUint32 theDequeSize=theDeque->GetSize();
if(0<theDequeSize){
PRInt32 index = 0;
const PRUnichar* theKeys[50] = {0,0,0,0,0}; // XXX - should be dynamic
const PRUnichar* theValues[50]= {0,0,0,0,0}; // XXX - should be dynamic
for(index=0; index<theAttrCount && index < 50; index++) {
theKeys[index] = aNode.GetKeyAt(index).GetUnicode();
theValues[index] = aNode.GetValueAt(index).GetUnicode();
}
nsAutoString charsetValue;
nsCharsetSource charsetSource;
nsAutoString theCharsetKey("charset");
nsAutoString theSourceKey("charsetSource");
nsAutoString intValue;
mParser->GetDocumentCharset(charsetValue, charsetSource);
// Add pseudo attribute in the end
if(index < 50) {
theKeys[index]=theCharsetKey.GetUnicode();
theValues[index] = charsetValue.GetUnicode();
index++;
}
if(index < 50) {
theKeys[index]=theSourceKey.GetUnicode();
PRInt32 sourceInt = charsetSource;
intValue.Append(sourceInt,10);
theValues[index] = intValue.GetUnicode();
index++;
}
CParserContext* pc=mParser->PeekContext();
void* theDocID=(pc) ? pc-> mKey : 0;
nsObserverNotifier theNotifier(aTag,index,theKeys,theValues,(PRUint32)theDocID);
theDeque->FirstThat(theNotifier);
result=theNotifier.mResult;
}//if
}
nsDeque* theDeque= (mParser && aTag != eHTMLTag_unknown)? (mParser->GetObserverDictionary()).GetObserversForTag(aTag):nsnull;
if(theDeque){
PRUint32 theDequeSize=theDeque->GetSize();
if(0<theDequeSize){
PRInt32 index = 0;
const PRUnichar* theKeys[50] = {0,0,0,0,0}; // XXX - should be dynamic
const PRUnichar* theValues[50]= {0,0,0,0,0}; // XXX - should be dynamic
for(index=0; index<theAttrCount && index < 50; index++) {
theKeys[index] = aNode.GetKeyAt(index).GetUnicode();
theValues[index] = aNode.GetValueAt(index).GetUnicode();
}
nsAutoString charsetValue;
nsCharsetSource charsetSource;
nsAutoString theCharsetKey("charset");
nsAutoString theSourceKey("charsetSource");
nsAutoString intValue;
mParser->GetDocumentCharset(charsetValue, charsetSource);
// Add pseudo attribute in the end
if(index < 50) {
theKeys[index]=theCharsetKey.GetUnicode();
theValues[index] = charsetValue.GetUnicode();
index++;
}
if(index < 50) {
theKeys[index]=theSourceKey.GetUnicode();
PRInt32 sourceInt = charsetSource;
intValue.Append(sourceInt,10);
theValues[index] = intValue.GetUnicode();
index++;
}
CParserContext* pc=mParser->PeekContext();
void* theDocID=(pc) ? pc-> mKey : 0;
nsObserverNotifier theNotifier((PRUnichar*)NS_EnumToTag(aTag),(PRUint32)theDocID,index,theKeys,theValues);
theDeque->FirstThat(theNotifier);
result=theNotifier.mResult;
}//if
}
@ -1564,7 +1524,7 @@ nsresult CNavDTD::HandleSavedTokensAbove(eHTMLTags aTag)
if(theTag != eHTMLTag_unknown) {
attrCount = theToken->GetAttributeCount();
// Put back attributes, which once got popped out, into the tokenizer
for(i=0;i<attrCount; i++){
for(PRInt32 j=0;j<attrCount; j++){
CToken* theAttrToken = mBodyContext->RestoreTokenFrom(theBadContentIndex);
if(theAttrToken) {
mTokenizer->PushTokenFront(theAttrToken);
@ -1582,7 +1542,7 @@ nsresult CNavDTD::HandleSavedTokensAbove(eHTMLTags aTag)
// Bad-contents were successfully processed. Now, itz time to get
// back to the original body context state.
for(PRInt32 j=0; j<(theTagCount - theTopIndex); j++)
for(PRInt32 k=0; k<(theTagCount - theTopIndex); k++)
mBodyContext->Push(temp.Pop());
// Terminate the new context and switch back to the main context

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

@ -44,7 +44,6 @@ CParserContext::CParserContext(nsScanner* aScanner,void* aKey,nsIStreamObserver*
mDTD=0;
mTransferBufferSize=eTransferBufferSize;
mParserEnabled=PR_TRUE;
mParserTerminated=PR_FALSE;
mStreamListenerState=eNone;
mMultipart=PR_TRUE;
mContextType=eCTNone;

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

@ -67,7 +67,6 @@ public:
void* mKey;
PRUint32 mTransferBufferSize;
PRBool mParserEnabled;
PRBool mParserTerminated;
eStreamState mStreamListenerState; //this is really only here for debug purposes.
PRBool mMultipart;
eContextType mContextType;

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

@ -642,8 +642,13 @@ PRUint32 AccumulateCRC(PRUint32 crc_accum, char *data_blk_ptr, int data_blk_size
******************************************************************************/
CObserverDictionary::CObserverDictionary() {
static nsString theTopicList[2] = {"htmlparser","xmlparser"};
PRInt32 theIndex=0;
nsCRT::zero(mObservers,sizeof(mObservers));
RegisterObservers();
while(theTopicList[theIndex].Length() > 0) {
RegisterObservers(theTopicList[theIndex]);
theIndex++;
}
}
CObserverDictionary::~CObserverDictionary() {
@ -667,21 +672,21 @@ void CObserverDictionary::UnregisterObservers() {
nsObserverReleaser theReleaser;
for(theIndex=0;theIndex<NS_HTML_TAG_MAX;theIndex++){
if(mObservers[theIndex]){
nsIElementObserver* theElementObserver=0;
mObservers[theIndex]->ForEach(theReleaser);
delete mObservers[theIndex];
}
}
}
void CObserverDictionary::RegisterObservers() {
void CObserverDictionary::RegisterObservers(nsString& aTopic) {
nsresult result = NS_OK;
nsIObserverService* theObserverService = nsnull;
result = nsServiceManager::GetService(NS_OBSERVERSERVICE_PROGID, nsIObserverService::GetIID(),
(nsISupports**) &theObserverService, nsnull);
if(result == NS_OK){
nsString theTopic("htmlparser");
nsIEnumerator* theEnum;
result = theObserverService->EnumerateObserverList(theTopic.GetUnicode(), &theEnum);
result = theObserverService->EnumerateObserverList(aTopic.GetUnicode(), &theEnum);
if(result == NS_OK){
nsIElementObserver* theElementObserver;
nsISupports *inst;
@ -695,8 +700,11 @@ void CObserverDictionary::RegisterObservers() {
PRUint32 theTagIndex = 0;
theTagStr = theElementObserver->GetTagNameAt(theTagIndex);
while (theTagStr != nsnull) {
eHTMLTags theTag = NS_TagToEnum(theTagStr);
if(eHTMLTag_userdefined!=theTag){
// XXX - HACK - Hardcoding PI for simplification. PI handling should not
// happen along with ** tags **. For now the specific PI, ?xml, is treated
// as an unknown tag in the dictionary!!!!
eHTMLTags theTag = (nsCRT::strcasecmp(theTagStr,"?xml") == 0)? eHTMLTag_unknown:NS_TagToEnum(theTagStr);
if(eHTMLTag_userdefined!=theTag && theTag < NS_HTML_TAG_MAX){
if(mObservers[theTag] == nsnull) {
mObservers[theTag] = new nsDeque(0);
}
@ -713,5 +721,7 @@ void CObserverDictionary::RegisterObservers() {
}
nsDeque* CObserverDictionary::GetObserversForTag(eHTMLTags aTag) {
return mObservers[aTag];
if(aTag < NS_HTML_TAG_MAX)
return mObservers[aTag];
return nsnull;
}

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

@ -247,7 +247,7 @@ public:
CObserverDictionary();
~CObserverDictionary();
void RegisterObservers();
void RegisterObservers(nsString& aTopicList);
void UnregisterObservers();
nsDeque* GetObserversForTag(eHTMLTags aTag);
@ -255,6 +255,38 @@ protected:
nsDeque* mObservers[NS_HTML_TAG_MAX];
};
/**************************************************************
Define the a functor used to notify observers...
**************************************************************/
class nsObserverNotifier: public nsDequeFunctor{
public:
nsObserverNotifier(const PRUnichar* aTagName,PRUint32 aUniqueKey,PRUint32 aCount=0,
const PRUnichar** aKeys=nsnull,const PRUnichar** aValues=nsnull){
mCount=aCount;
mKeys=aKeys;
mValues=aValues;
mUniqueKey=aUniqueKey;
mTagName=aTagName;
}
virtual void* operator()(void* anObject) {
nsIElementObserver* theObserver= (nsIElementObserver*)anObject;
if(theObserver) {
mResult = theObserver->Notify(mUniqueKey,mTagName,mCount,mKeys,mValues);
}
if(NS_OK==mResult)
return 0;
return anObject;
}
const PRUnichar** mKeys;
const PRUnichar** mValues;
PRUint32 mCount;
PRUint32 mUniqueKey;
nsresult mResult;
const PRUnichar* mTagName;
};
#endif

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

@ -191,6 +191,7 @@ nsParser::nsParser(nsITokenObserver* anObserver) : mCommand(""), mUnusedInput(""
mTokenObserver=anObserver;
mStreamStatus=0;
mDTDVerification=PR_FALSE;
mParserTerminated=PR_FALSE;
mCharsetSource=kCharsetUninitialized;
mInternalState=NS_OK;
}
@ -584,9 +585,8 @@ void nsParser::SetUnusedInput(nsString& aBuffer) {
* @return should return NS_OK once implemented
*/
nsresult nsParser::Terminate(void){
NS_NOTYETIMPLEMENTED("Call again later");
nsresult result=NS_ERROR_NOT_IMPLEMENTED;
return result;
mParserTerminated=PR_TRUE;
return NS_OK;
}
/**
@ -870,7 +870,7 @@ nsresult nsParser::ParseFragment(const nsString& aSourceBuffer,void* aKey,nsITag
nsresult nsParser::ResumeParse(nsIDTD* aDefaultDTD, PRBool aIsFinalChunk) {
nsresult result=NS_OK;
if(mParserContext->mParserEnabled && !mParserContext->mParserTerminated) {
if(mParserContext->mParserEnabled && !mParserTerminated) {
result=WillBuildModel(mParserContext->mScanner->GetFilename(),aDefaultDTD);
if(mParserContext->mDTD) {
mParserContext->mDTD->WillResumeParse();
@ -878,7 +878,7 @@ nsresult nsParser::ResumeParse(nsIDTD* aDefaultDTD, PRBool aIsFinalChunk) {
result=Tokenize(aIsFinalChunk);
result=BuildModel();
if((!mParserContext->mMultipart) || (mParserContext->mParserTerminated) ||
if((!mParserContext->mMultipart) || (mParserTerminated) ||
((eOnStop==mParserContext->mStreamListenerState) && (NS_OK==result))){
DidBuildModel(mStreamStatus);
}
@ -931,7 +931,7 @@ nsresult nsParser::BuildModel() {
if(theRootDTD) {
result=theRootDTD->BuildModel(this,theTokenizer,mTokenObserver,mSink);
if(NS_ERROR_HTMLPARSER_STOPPARSING==result)
mParserContext->mParserTerminated=PR_TRUE;
Terminate();
}
}
else{
@ -1253,7 +1253,7 @@ nsresult nsParser::Tokenize(PRBool aIsFinalChunk){
break;
}
else if(NS_ERROR_HTMLPARSER_STOPPARSING==result)
mParserContext->mParserTerminated=PR_TRUE;
Terminate();
}
}
DidTokenize(aIsFinalChunk);

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

@ -63,6 +63,7 @@
#include "nsParserCIID.h"
#include "nsITokenizer.h"
#include "nsHTMLTags.h"
#include "nsDTDUtils.h"
class IContentSink;
class nsIDTD;
@ -278,6 +279,14 @@ friend class CTokenHandler;
*/
virtual nsresult CreateTagStack(nsITagStack** aTagStack);
/**
* Call this to access observer dictionary ( internal to parser )
* @update harishd 06/27/99
* @param
* @return
*/
CObserverDictionary& GetObserverDictionary(void) { return mObserverDictionary; }
protected:
/**
@ -361,6 +370,7 @@ protected:
nsIContentSink* mSink;
nsIParserFilter* mParserFilter;
PRBool mDTDVerification;
PRBool mParserTerminated;
nsString mCommand;
PRInt32 mStreamStatus;
nsITokenObserver* mTokenObserver;
@ -368,6 +378,7 @@ protected:
nsString mCharset;
nsCharsetSource mCharsetSource;
nsresult mInternalState;
CObserverDictionary mObserverDictionary;
};

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

@ -410,6 +410,29 @@ PRBool CWellFormedDTD::IsContainer(PRInt32 aTag) const{
return result;
}
/**
* Helper method that filters out the PI from a given string.
*
*
* @update harishd 06/27/99
* @param aPIString -- string that contains the PI.
* @param aPI -- PI that's filtered out from aPIString.
* @return
*/
void GetProcessingInstruction(const nsString& aPIString, char* a_PI)
{
static nsAutoString theWS2("\b\t\n ");
if(aPIString.Length() > 0) {
nsString temp;
PRInt32 theOffset = aPIString.FindCharInSet(theWS2,1);
aPIString.Mid(temp,1,theOffset);
temp.ToCString(a_PI,temp.Length());
}
return;
}
/**
*
* @update vidur 11/12/98
@ -441,8 +464,24 @@ NS_IMETHODIMP CWellFormedDTD::HandleToken(CToken* aToken,nsIParser* aParser) {
break;
case eToken_instruction:
result=mSink->AddProcessingInstruction(theNode);
break;
{
char thePI[30]={0};
nsString& thePIString = theToken->GetStringValueXXX();
GetProcessingInstruction(thePIString,thePI);
// XXX - HACK - The current observer dictionary is tag based. Converting it to be string based
// might cause some overhead. Until we figure out a better solution, in handling PIs and tags, I'm hardcoding
// a specific PI observer-list to be notified.
eHTMLTags theTag = (nsCRT::strcasecmp(thePI,"?xml") == 0)? eHTMLTag_unknown:eHTMLTag_userdefined;
nsDeque* theDeque= (mParser)? (mParser->GetObserverDictionary()).GetObserversForTag(theTag):nsnull;
if(theDeque) {
CParserContext* pc=mParser->PeekContext();
void* theDocID=(pc) ? pc-> mKey : 0;
nsObserverNotifier theNotifier(thePIString.GetUnicode(),(PRUint32)theDocID);
theDeque->FirstThat(theNotifier);
}
result=mSink->AddProcessingInstruction(theNode);
break;
}
case eToken_start:
{

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

@ -1034,39 +1034,7 @@ void WriteTokenToLog(CToken* aToken) {
aToken->DebugDumpSource(outputStream); //write token without close bracket...
}
#endif
/**************************************************************
Define the a functor used to notify observers...
**************************************************************/
class nsObserverNotifier: public nsDequeFunctor{
public:
nsObserverNotifier(eHTMLTags aTag,PRUint32 aCount,const PRUnichar** aKeys,
const PRUnichar** aValues,PRUint32 aUniqueKey){
mCount=aCount;
mKeys=aKeys;
mValues=aValues;
mUniqueKey=aUniqueKey;
mTag=aTag;
}
virtual void* operator()(void* anObject) {
nsIElementObserver* theObserver= (nsIElementObserver*)anObject;
if(theObserver) {
mResult = theObserver->Notify(mUniqueKey,mTag,mCount,mKeys,mValues);
}
if(NS_OK==mResult)
return 0;
return anObject;
}
const PRUnichar** mKeys;
const PRUnichar** mValues;
PRUint32 mCount;
PRUint32 mUniqueKey;
nsresult mResult;
eHTMLTags mTag;
};
/**
* This gets called before we've handled a given start tag.
* It's a generic hook to let us do pre processing.
@ -1084,53 +1052,45 @@ nsresult CNavDTD::WillHandleStartTag(CToken* aToken,eHTMLTags aTag,nsCParserNode
result=CollectSkippedContent(aNode,theAttrCount);
}
/**********************************************************
/**********************************************************
THIS WILL ULTIMATELY BECOME THE REAL OBSERVER API...
**********************************************************/
static CObserverDictionary gObserverDictionary;
if(aTag < NS_HTML_TAG_MAX){
nsDeque* theDeque=gObserverDictionary.GetObserversForTag(aTag);
if(theDeque){
PRUint32 theDequeSize=theDeque->GetSize();
if(0<theDequeSize){
PRInt32 index = 0;
const PRUnichar* theKeys[50] = {0,0,0,0,0}; // XXX - should be dynamic
const PRUnichar* theValues[50]= {0,0,0,0,0}; // XXX - should be dynamic
for(index=0; index<theAttrCount && index < 50; index++) {
theKeys[index] = aNode.GetKeyAt(index).GetUnicode();
theValues[index] = aNode.GetValueAt(index).GetUnicode();
}
nsAutoString charsetValue;
nsCharsetSource charsetSource;
nsAutoString theCharsetKey("charset");
nsAutoString theSourceKey("charsetSource");
nsAutoString intValue;
mParser->GetDocumentCharset(charsetValue, charsetSource);
// Add pseudo attribute in the end
if(index < 50) {
theKeys[index]=theCharsetKey.GetUnicode();
theValues[index] = charsetValue.GetUnicode();
index++;
}
if(index < 50) {
theKeys[index]=theSourceKey.GetUnicode();
PRInt32 sourceInt = charsetSource;
intValue.Append(sourceInt,10);
theValues[index] = intValue.GetUnicode();
index++;
}
CParserContext* pc=mParser->PeekContext();
void* theDocID=(pc) ? pc-> mKey : 0;
nsObserverNotifier theNotifier(aTag,index,theKeys,theValues,(PRUint32)theDocID);
theDeque->FirstThat(theNotifier);
result=theNotifier.mResult;
}//if
}
nsDeque* theDeque= (mParser && aTag != eHTMLTag_unknown)? (mParser->GetObserverDictionary()).GetObserversForTag(aTag):nsnull;
if(theDeque){
PRUint32 theDequeSize=theDeque->GetSize();
if(0<theDequeSize){
PRInt32 index = 0;
const PRUnichar* theKeys[50] = {0,0,0,0,0}; // XXX - should be dynamic
const PRUnichar* theValues[50]= {0,0,0,0,0}; // XXX - should be dynamic
for(index=0; index<theAttrCount && index < 50; index++) {
theKeys[index] = aNode.GetKeyAt(index).GetUnicode();
theValues[index] = aNode.GetValueAt(index).GetUnicode();
}
nsAutoString charsetValue;
nsCharsetSource charsetSource;
nsAutoString theCharsetKey("charset");
nsAutoString theSourceKey("charsetSource");
nsAutoString intValue;
mParser->GetDocumentCharset(charsetValue, charsetSource);
// Add pseudo attribute in the end
if(index < 50) {
theKeys[index]=theCharsetKey.GetUnicode();
theValues[index] = charsetValue.GetUnicode();
index++;
}
if(index < 50) {
theKeys[index]=theSourceKey.GetUnicode();
PRInt32 sourceInt = charsetSource;
intValue.Append(sourceInt,10);
theValues[index] = intValue.GetUnicode();
index++;
}
CParserContext* pc=mParser->PeekContext();
void* theDocID=(pc) ? pc-> mKey : 0;
nsObserverNotifier theNotifier((PRUnichar*)NS_EnumToTag(aTag),(PRUint32)theDocID,index,theKeys,theValues);
theDeque->FirstThat(theNotifier);
result=theNotifier.mResult;
}//if
}
@ -1564,7 +1524,7 @@ nsresult CNavDTD::HandleSavedTokensAbove(eHTMLTags aTag)
if(theTag != eHTMLTag_unknown) {
attrCount = theToken->GetAttributeCount();
// Put back attributes, which once got popped out, into the tokenizer
for(i=0;i<attrCount; i++){
for(PRInt32 j=0;j<attrCount; j++){
CToken* theAttrToken = mBodyContext->RestoreTokenFrom(theBadContentIndex);
if(theAttrToken) {
mTokenizer->PushTokenFront(theAttrToken);
@ -1582,7 +1542,7 @@ nsresult CNavDTD::HandleSavedTokensAbove(eHTMLTags aTag)
// Bad-contents were successfully processed. Now, itz time to get
// back to the original body context state.
for(PRInt32 j=0; j<(theTagCount - theTopIndex); j++)
for(PRInt32 k=0; k<(theTagCount - theTopIndex); k++)
mBodyContext->Push(temp.Pop());
// Terminate the new context and switch back to the main context

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

@ -44,7 +44,6 @@ CParserContext::CParserContext(nsScanner* aScanner,void* aKey,nsIStreamObserver*
mDTD=0;
mTransferBufferSize=eTransferBufferSize;
mParserEnabled=PR_TRUE;
mParserTerminated=PR_FALSE;
mStreamListenerState=eNone;
mMultipart=PR_TRUE;
mContextType=eCTNone;

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

@ -67,7 +67,6 @@ public:
void* mKey;
PRUint32 mTransferBufferSize;
PRBool mParserEnabled;
PRBool mParserTerminated;
eStreamState mStreamListenerState; //this is really only here for debug purposes.
PRBool mMultipart;
eContextType mContextType;

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

@ -642,8 +642,13 @@ PRUint32 AccumulateCRC(PRUint32 crc_accum, char *data_blk_ptr, int data_blk_size
******************************************************************************/
CObserverDictionary::CObserverDictionary() {
static nsString theTopicList[2] = {"htmlparser","xmlparser"};
PRInt32 theIndex=0;
nsCRT::zero(mObservers,sizeof(mObservers));
RegisterObservers();
while(theTopicList[theIndex].Length() > 0) {
RegisterObservers(theTopicList[theIndex]);
theIndex++;
}
}
CObserverDictionary::~CObserverDictionary() {
@ -667,21 +672,21 @@ void CObserverDictionary::UnregisterObservers() {
nsObserverReleaser theReleaser;
for(theIndex=0;theIndex<NS_HTML_TAG_MAX;theIndex++){
if(mObservers[theIndex]){
nsIElementObserver* theElementObserver=0;
mObservers[theIndex]->ForEach(theReleaser);
delete mObservers[theIndex];
}
}
}
void CObserverDictionary::RegisterObservers() {
void CObserverDictionary::RegisterObservers(nsString& aTopic) {
nsresult result = NS_OK;
nsIObserverService* theObserverService = nsnull;
result = nsServiceManager::GetService(NS_OBSERVERSERVICE_PROGID, nsIObserverService::GetIID(),
(nsISupports**) &theObserverService, nsnull);
if(result == NS_OK){
nsString theTopic("htmlparser");
nsIEnumerator* theEnum;
result = theObserverService->EnumerateObserverList(theTopic.GetUnicode(), &theEnum);
result = theObserverService->EnumerateObserverList(aTopic.GetUnicode(), &theEnum);
if(result == NS_OK){
nsIElementObserver* theElementObserver;
nsISupports *inst;
@ -695,8 +700,11 @@ void CObserverDictionary::RegisterObservers() {
PRUint32 theTagIndex = 0;
theTagStr = theElementObserver->GetTagNameAt(theTagIndex);
while (theTagStr != nsnull) {
eHTMLTags theTag = NS_TagToEnum(theTagStr);
if(eHTMLTag_userdefined!=theTag){
// XXX - HACK - Hardcoding PI for simplification. PI handling should not
// happen along with ** tags **. For now the specific PI, ?xml, is treated
// as an unknown tag in the dictionary!!!!
eHTMLTags theTag = (nsCRT::strcasecmp(theTagStr,"?xml") == 0)? eHTMLTag_unknown:NS_TagToEnum(theTagStr);
if(eHTMLTag_userdefined!=theTag && theTag < NS_HTML_TAG_MAX){
if(mObservers[theTag] == nsnull) {
mObservers[theTag] = new nsDeque(0);
}
@ -713,5 +721,7 @@ void CObserverDictionary::RegisterObservers() {
}
nsDeque* CObserverDictionary::GetObserversForTag(eHTMLTags aTag) {
return mObservers[aTag];
if(aTag < NS_HTML_TAG_MAX)
return mObservers[aTag];
return nsnull;
}

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

@ -247,7 +247,7 @@ public:
CObserverDictionary();
~CObserverDictionary();
void RegisterObservers();
void RegisterObservers(nsString& aTopicList);
void UnregisterObservers();
nsDeque* GetObserversForTag(eHTMLTags aTag);
@ -255,6 +255,38 @@ protected:
nsDeque* mObservers[NS_HTML_TAG_MAX];
};
/**************************************************************
Define the a functor used to notify observers...
**************************************************************/
class nsObserverNotifier: public nsDequeFunctor{
public:
nsObserverNotifier(const PRUnichar* aTagName,PRUint32 aUniqueKey,PRUint32 aCount=0,
const PRUnichar** aKeys=nsnull,const PRUnichar** aValues=nsnull){
mCount=aCount;
mKeys=aKeys;
mValues=aValues;
mUniqueKey=aUniqueKey;
mTagName=aTagName;
}
virtual void* operator()(void* anObject) {
nsIElementObserver* theObserver= (nsIElementObserver*)anObject;
if(theObserver) {
mResult = theObserver->Notify(mUniqueKey,mTagName,mCount,mKeys,mValues);
}
if(NS_OK==mResult)
return 0;
return anObject;
}
const PRUnichar** mKeys;
const PRUnichar** mValues;
PRUint32 mCount;
PRUint32 mUniqueKey;
nsresult mResult;
const PRUnichar* mTagName;
};
#endif

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

@ -191,6 +191,7 @@ nsParser::nsParser(nsITokenObserver* anObserver) : mCommand(""), mUnusedInput(""
mTokenObserver=anObserver;
mStreamStatus=0;
mDTDVerification=PR_FALSE;
mParserTerminated=PR_FALSE;
mCharsetSource=kCharsetUninitialized;
mInternalState=NS_OK;
}
@ -584,9 +585,8 @@ void nsParser::SetUnusedInput(nsString& aBuffer) {
* @return should return NS_OK once implemented
*/
nsresult nsParser::Terminate(void){
NS_NOTYETIMPLEMENTED("Call again later");
nsresult result=NS_ERROR_NOT_IMPLEMENTED;
return result;
mParserTerminated=PR_TRUE;
return NS_OK;
}
/**
@ -870,7 +870,7 @@ nsresult nsParser::ParseFragment(const nsString& aSourceBuffer,void* aKey,nsITag
nsresult nsParser::ResumeParse(nsIDTD* aDefaultDTD, PRBool aIsFinalChunk) {
nsresult result=NS_OK;
if(mParserContext->mParserEnabled && !mParserContext->mParserTerminated) {
if(mParserContext->mParserEnabled && !mParserTerminated) {
result=WillBuildModel(mParserContext->mScanner->GetFilename(),aDefaultDTD);
if(mParserContext->mDTD) {
mParserContext->mDTD->WillResumeParse();
@ -878,7 +878,7 @@ nsresult nsParser::ResumeParse(nsIDTD* aDefaultDTD, PRBool aIsFinalChunk) {
result=Tokenize(aIsFinalChunk);
result=BuildModel();
if((!mParserContext->mMultipart) || (mParserContext->mParserTerminated) ||
if((!mParserContext->mMultipart) || (mParserTerminated) ||
((eOnStop==mParserContext->mStreamListenerState) && (NS_OK==result))){
DidBuildModel(mStreamStatus);
}
@ -931,7 +931,7 @@ nsresult nsParser::BuildModel() {
if(theRootDTD) {
result=theRootDTD->BuildModel(this,theTokenizer,mTokenObserver,mSink);
if(NS_ERROR_HTMLPARSER_STOPPARSING==result)
mParserContext->mParserTerminated=PR_TRUE;
Terminate();
}
}
else{
@ -1253,7 +1253,7 @@ nsresult nsParser::Tokenize(PRBool aIsFinalChunk){
break;
}
else if(NS_ERROR_HTMLPARSER_STOPPARSING==result)
mParserContext->mParserTerminated=PR_TRUE;
Terminate();
}
}
DidTokenize(aIsFinalChunk);

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

@ -63,6 +63,7 @@
#include "nsParserCIID.h"
#include "nsITokenizer.h"
#include "nsHTMLTags.h"
#include "nsDTDUtils.h"
class IContentSink;
class nsIDTD;
@ -278,6 +279,14 @@ friend class CTokenHandler;
*/
virtual nsresult CreateTagStack(nsITagStack** aTagStack);
/**
* Call this to access observer dictionary ( internal to parser )
* @update harishd 06/27/99
* @param
* @return
*/
CObserverDictionary& GetObserverDictionary(void) { return mObserverDictionary; }
protected:
/**
@ -361,6 +370,7 @@ protected:
nsIContentSink* mSink;
nsIParserFilter* mParserFilter;
PRBool mDTDVerification;
PRBool mParserTerminated;
nsString mCommand;
PRInt32 mStreamStatus;
nsITokenObserver* mTokenObserver;
@ -368,6 +378,7 @@ protected:
nsString mCharset;
nsCharsetSource mCharsetSource;
nsresult mInternalState;
CObserverDictionary mObserverDictionary;
};

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

@ -410,6 +410,29 @@ PRBool CWellFormedDTD::IsContainer(PRInt32 aTag) const{
return result;
}
/**
* Helper method that filters out the PI from a given string.
*
*
* @update harishd 06/27/99
* @param aPIString -- string that contains the PI.
* @param aPI -- PI that's filtered out from aPIString.
* @return
*/
void GetProcessingInstruction(const nsString& aPIString, char* a_PI)
{
static nsAutoString theWS2("\b\t\n ");
if(aPIString.Length() > 0) {
nsString temp;
PRInt32 theOffset = aPIString.FindCharInSet(theWS2,1);
aPIString.Mid(temp,1,theOffset);
temp.ToCString(a_PI,temp.Length());
}
return;
}
/**
*
* @update vidur 11/12/98
@ -441,8 +464,24 @@ NS_IMETHODIMP CWellFormedDTD::HandleToken(CToken* aToken,nsIParser* aParser) {
break;
case eToken_instruction:
result=mSink->AddProcessingInstruction(theNode);
break;
{
char thePI[30]={0};
nsString& thePIString = theToken->GetStringValueXXX();
GetProcessingInstruction(thePIString,thePI);
// XXX - HACK - The current observer dictionary is tag based. Converting it to be string based
// might cause some overhead. Until we figure out a better solution, in handling PIs and tags, I'm hardcoding
// a specific PI observer-list to be notified.
eHTMLTags theTag = (nsCRT::strcasecmp(thePI,"?xml") == 0)? eHTMLTag_unknown:eHTMLTag_userdefined;
nsDeque* theDeque= (mParser)? (mParser->GetObserverDictionary()).GetObserversForTag(theTag):nsnull;
if(theDeque) {
CParserContext* pc=mParser->PeekContext();
void* theDocID=(pc) ? pc-> mKey : 0;
nsObserverNotifier theNotifier(thePIString.GetUnicode(),(PRUint32)theDocID);
theDeque->FirstThat(theNotifier);
}
result=mSink->AddProcessingInstruction(theNode);
break;
}
case eToken_start:
{