Added Observernotification for XML PI, cleaned up some warnings.
This commit is contained in:
Родитель
cfb99ec34c
Коммит
9ddffbdebc
|
@ -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:
|
||||
{
|
||||
|
|
Загрузка…
Ссылка в новой задаче