зеркало из https://github.com/mozilla/pjs.git
Cleaned up some code.
Fixed bugs 5974, 12641, and 12389.
This commit is contained in:
Родитель
1677a4153a
Коммит
bd73964c84
|
@ -1079,90 +1079,58 @@ nsresult CNavDTD::WillHandleStartTag(CToken* aToken,eHTMLTags aTag,nsCParserNode
|
||||||
result=CollectSkippedContent(aNode,theAttrCount);
|
result=CollectSkippedContent(aNode,theAttrCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**********************************************************
|
if(mParser) {
|
||||||
THIS WILL ULTIMATELY BECOME THE REAL OBSERVER API...
|
nsAutoString charsetValue;
|
||||||
**********************************************************/
|
nsCharsetSource charsetSource;
|
||||||
nsDeque* theDeque= (mParser && aTag != eHTMLTag_unknown)? (mParser->GetObserverDictionary()).GetObserversForTag(aTag):nsnull;
|
mParser->GetDocumentCharset(charsetValue,charsetSource);
|
||||||
if(theDeque){
|
CParserContext* pc=mParser->PeekContext();
|
||||||
PRUint32 theDequeSize=theDeque->GetSize();
|
void* theDocID=(pc) ? pc->mKey : 0;
|
||||||
if(0<theDequeSize){
|
result=(mParser->GetObserverService()).Notify(aTag,aNode,(PRUint32)theDocID,this,charsetValue,charsetSource);
|
||||||
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++;
|
|
||||||
}
|
|
||||||
nsAutoString theTagStr(nsHTMLTags::GetStringValue(aTag));
|
|
||||||
CParserContext* pc=mParser->PeekContext();
|
|
||||||
void* theDocID=(pc) ? pc-> mKey : 0;
|
|
||||||
nsObserverNotifier theNotifier(theTagStr.GetUnicode(),(PRUint32)theDocID,index,theKeys,theValues);
|
|
||||||
theDeque->FirstThat(theNotifier);
|
|
||||||
result=theNotifier.mResult;
|
|
||||||
}//if
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if(eHTMLTag_meta==aTag) {
|
|
||||||
PRInt32 theCount=aNode.GetAttributeCount();
|
|
||||||
if(1<theCount){
|
|
||||||
|
|
||||||
const nsString& theKey=aNode.GetKeyAt(0);
|
|
||||||
if(theKey.EqualsIgnoreCase("NAME")) {
|
|
||||||
const nsString& theValue1=aNode.GetValueAt(0);
|
|
||||||
if(theValue1.EqualsIgnoreCase("\"CRC\"")) {
|
|
||||||
const nsString& theKey2=aNode.GetKeyAt(1);
|
|
||||||
if(theKey2.EqualsIgnoreCase("CONTENT")) {
|
|
||||||
const nsString& theValue2=aNode.GetValueAt(1);
|
|
||||||
PRInt32 err=0;
|
|
||||||
mExpectedCRC32=theValue2.ToInteger(&err);
|
|
||||||
} //if
|
|
||||||
} //if
|
|
||||||
} //else
|
|
||||||
|
|
||||||
} //if
|
|
||||||
}//if
|
|
||||||
|
|
||||||
if(NS_OK==result) {
|
|
||||||
result=gHTMLElements[aTag].HasSpecialProperty(kDiscardTag) ? 1 : NS_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
PRBool isHeadChild=gHTMLElements[eHTMLTag_head].IsChildOfHead(aTag);
|
|
||||||
|
|
||||||
//this code is here to make sure the head is closed before we deal
|
if(NS_SUCCEEDED(result)) {
|
||||||
//with any tags that don't belong in the head.
|
if(eHTMLTag_meta==aTag) {
|
||||||
if(NS_OK==result) {
|
PRInt32 theCount=aNode.GetAttributeCount();
|
||||||
if(mHasOpenHead){
|
if(1<theCount){
|
||||||
static eHTMLTags skip2[]={eHTMLTag_newline,eHTMLTag_whitespace};
|
|
||||||
if(!FindTagInSet(aTag,skip2,sizeof(skip2)/sizeof(eHTMLTag_unknown))){
|
const nsString& theKey=aNode.GetKeyAt(0);
|
||||||
if(!isHeadChild){
|
if(theKey.EqualsIgnoreCase("NAME")) {
|
||||||
CEndToken theToken(eHTMLTag_head);
|
const nsString& theValue1=aNode.GetValueAt(0);
|
||||||
nsCParserNode theNode(&theToken,mLineNumber);
|
if(theValue1.EqualsIgnoreCase("\"CRC\"")) {
|
||||||
result=CloseHead(theNode);
|
const nsString& theKey2=aNode.GetKeyAt(1);
|
||||||
|
if(theKey2.EqualsIgnoreCase("CONTENT")) {
|
||||||
|
const nsString& theValue2=aNode.GetValueAt(1);
|
||||||
|
PRInt32 err=0;
|
||||||
|
mExpectedCRC32=theValue2.ToInteger(&err);
|
||||||
|
} //if
|
||||||
|
} //if
|
||||||
|
} //else
|
||||||
|
|
||||||
|
} //if
|
||||||
|
}//if
|
||||||
|
|
||||||
|
if(NS_OK==result) {
|
||||||
|
result=gHTMLElements[aTag].HasSpecialProperty(kDiscardTag) ? 1 : NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
PRBool isHeadChild=gHTMLElements[eHTMLTag_head].IsChildOfHead(aTag);
|
||||||
|
|
||||||
|
//this code is here to make sure the head is closed before we deal
|
||||||
|
//with any tags that don't belong in the head.
|
||||||
|
if(NS_OK==result) {
|
||||||
|
if(mHasOpenHead){
|
||||||
|
static eHTMLTags skip2[]={eHTMLTag_newline,eHTMLTag_whitespace};
|
||||||
|
if(!FindTagInSet(aTag,skip2,sizeof(skip2)/sizeof(eHTMLTag_unknown))){
|
||||||
|
if(!isHeadChild){
|
||||||
|
CEndToken theToken(eHTMLTag_head);
|
||||||
|
nsCParserNode theNode(&theToken,mLineNumber);
|
||||||
|
result=CloseHead(theNode);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1302,6 +1270,11 @@ nsresult CNavDTD::HandleStartToken(CToken* aToken) {
|
||||||
result=mSink->AddLeaf(*theNode);
|
result=mSink->AddLeaf(*theNode);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case eHTMLTag_image:
|
||||||
|
aToken->SetTypeID(theChildTag=eHTMLTag_img);
|
||||||
|
result=HandleDefaultStartToken(aToken,theChildTag,*theNode);
|
||||||
|
break;
|
||||||
|
|
||||||
case eHTMLTag_userdefined:
|
case eHTMLTag_userdefined:
|
||||||
break; //drop them on the floor for now...
|
break; //drop them on the floor for now...
|
||||||
|
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
|
|
||||||
#include "nsDTDUtils.h"
|
#include "nsDTDUtils.h"
|
||||||
#include "CNavDTD.h"
|
#include "CNavDTD.h"
|
||||||
|
#include "nsIParserNode.h"
|
||||||
|
|
||||||
#include "nsIObserverService.h"
|
#include "nsIObserverService.h"
|
||||||
#include "nsIServiceManager.h"
|
#include "nsIServiceManager.h"
|
||||||
|
@ -640,7 +641,7 @@ PRUint32 AccumulateCRC(PRUint32 crc_accum, char *data_blk_ptr, int data_blk_size
|
||||||
come and go on a document basis.
|
come and go on a document basis.
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
||||||
CObserverDictionary::CObserverDictionary() {
|
CObserverService::CObserverService() {
|
||||||
|
|
||||||
nsCRT::zero(mObservers,sizeof(mObservers));
|
nsCRT::zero(mObservers,sizeof(mObservers));
|
||||||
|
|
||||||
|
@ -652,7 +653,7 @@ CObserverDictionary::CObserverDictionary() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CObserverDictionary::~CObserverDictionary() {
|
CObserverService::~CObserverService() {
|
||||||
UnregisterObservers();
|
UnregisterObservers();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -668,19 +669,34 @@ public:
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
void CObserverDictionary::UnregisterObservers() {
|
/**
|
||||||
|
* Release observers and empty the observer array.
|
||||||
|
*
|
||||||
|
* @update harishd 08/29/99
|
||||||
|
* @param
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
|
||||||
|
void CObserverService::UnregisterObservers() {
|
||||||
int theIndex=0;
|
int theIndex=0;
|
||||||
nsObserverReleaser theReleaser;
|
nsObserverReleaser theReleaser;
|
||||||
for(theIndex=0;theIndex<=NS_HTML_TAG_MAX;theIndex++){
|
for(theIndex=0;theIndex<=NS_HTML_TAG_MAX;theIndex++){
|
||||||
if(mObservers[theIndex]){
|
if(mObservers[theIndex]){
|
||||||
//nsIElementObserver* theElementObserver=0;
|
|
||||||
mObservers[theIndex]->ForEach(theReleaser);
|
mObservers[theIndex]->ForEach(theReleaser);
|
||||||
delete mObservers[theIndex];
|
delete mObservers[theIndex];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CObserverDictionary::RegisterObservers(nsString& aTopic) {
|
/**
|
||||||
|
* This method will maintain lists of observers registered for specific tags.
|
||||||
|
*
|
||||||
|
* @update harishd 08/29/99
|
||||||
|
* @param aTopic - The topic under which observers register for.
|
||||||
|
* @return if SUCCESS return NS_OK else return ERROR code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void CObserverService::RegisterObservers(nsString& aTopic) {
|
||||||
nsresult result = NS_OK;
|
nsresult result = NS_OK;
|
||||||
nsIObserverService* theObserverService = nsnull;
|
nsIObserverService* theObserverService = nsnull;
|
||||||
result = nsServiceManager::GetService(NS_OBSERVERSERVICE_PROGID, nsIObserverService::GetIID(),
|
result = nsServiceManager::GetService(NS_OBSERVERSERVICE_PROGID, nsIObserverService::GetIID(),
|
||||||
|
@ -703,22 +719,16 @@ void CObserverDictionary::RegisterObservers(nsString& aTopic) {
|
||||||
PRUint32 theTagIndex = 0;
|
PRUint32 theTagIndex = 0;
|
||||||
theTagStr = theElementObserver->GetTagNameAt(theTagIndex);
|
theTagStr = theElementObserver->GetTagNameAt(theTagIndex);
|
||||||
while (theTagStr != nsnull) {
|
while (theTagStr != nsnull) {
|
||||||
// XXX - HACK - Hardcoding PI for simplification. PI handling should not
|
eHTMLTags theTag = nsHTMLTags::LookupTag(nsCAutoString(theTagStr));
|
||||||
// happen along with ** tags **. For now the specific PI, ?xml, is treated
|
|
||||||
// as an unknown tag in the dictionary!!!!
|
|
||||||
eHTMLTags theTag = (nsCRT::strcmp(theTagStr,"?xml") == 0) ? eHTMLTag_unknown :
|
|
||||||
nsHTMLTags::LookupTag(nsCAutoString(theTagStr));
|
|
||||||
if((eHTMLTag_userdefined!=theTag) && (theTag <= NS_HTML_TAG_MAX)){
|
if((eHTMLTag_userdefined!=theTag) && (theTag <= NS_HTML_TAG_MAX)){
|
||||||
if(mObservers[theTag] == nsnull) {
|
if(mObservers[theTag] == nsnull) {
|
||||||
mObservers[theTag] = new nsDeque(0);
|
mObservers[theTag] = new nsDeque(0);
|
||||||
}
|
}
|
||||||
NS_ADDREF(theElementObserver);
|
|
||||||
mObservers[theTag]->Push(theElementObserver);
|
mObservers[theTag]->Push(theElementObserver);
|
||||||
}
|
}
|
||||||
theTagIndex++;
|
theTagIndex++;
|
||||||
theTagStr = theElementObserver->GetTagNameAt(theTagIndex);
|
theTagStr = theElementObserver->GetTagNameAt(theTagIndex);
|
||||||
}
|
}
|
||||||
NS_RELEASE(theElementObserver);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -726,7 +736,69 @@ void CObserverDictionary::RegisterObservers(nsString& aTopic) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
nsDeque* CObserverDictionary::GetObserversForTag(eHTMLTags aTag) {
|
/**
|
||||||
|
* This method will notify observers registered for specific tags.
|
||||||
|
*
|
||||||
|
* @update harishd 08/29/99
|
||||||
|
* @param aTag - The tag for which observers could be waiting for.
|
||||||
|
* @param aNode -
|
||||||
|
* @param aUniqueID - The document ID.
|
||||||
|
* @param aDTD - The current DTD.
|
||||||
|
* @param aCharsetValue -
|
||||||
|
* @param aCharsetSource -
|
||||||
|
* @return if SUCCESS return NS_OK else return ERROR code.
|
||||||
|
*/
|
||||||
|
nsresult CObserverService::Notify(eHTMLTags aTag,nsIParserNode& aNode,PRUint32 aUniqueID, nsIDTD* aDTD,
|
||||||
|
nsAutoString& aCharsetValue,nsCharsetSource& aCharsetSource) {
|
||||||
|
nsresult result=NS_OK;
|
||||||
|
nsDeque* theDeque=GetObserversForTag(aTag);
|
||||||
|
if(theDeque){
|
||||||
|
PRInt32 theAttrCount =aNode.GetAttributeCount();
|
||||||
|
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 theCharsetKey("charset");
|
||||||
|
nsAutoString theSourceKey("charsetSource");
|
||||||
|
nsAutoString intValue;
|
||||||
|
// Add pseudo attribute in the end
|
||||||
|
if(index < 50) {
|
||||||
|
theKeys[index]=theCharsetKey.GetUnicode();
|
||||||
|
theValues[index] = aCharsetValue.GetUnicode();
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
if(index < 50) {
|
||||||
|
theKeys[index]=theSourceKey.GetUnicode();
|
||||||
|
PRInt32 sourceInt = aCharsetSource;
|
||||||
|
intValue.Append(sourceInt,10);
|
||||||
|
theValues[index] = intValue.GetUnicode();
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
nsAutoString theTagStr(nsHTMLTags::GetStringValue(aTag));
|
||||||
|
nsObserverNotifier theNotifier(theTagStr.GetUnicode(),aUniqueID,index,theKeys,theValues);
|
||||||
|
theDeque->FirstThat(theNotifier);
|
||||||
|
result=theNotifier.mResult;
|
||||||
|
}//if
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method will look for the list of observers registered for
|
||||||
|
* a specific tag.
|
||||||
|
*
|
||||||
|
* @update harishd 08/29/99
|
||||||
|
* @param aTag - The tag for which observers could be waiting for.
|
||||||
|
* @return if FOUND return "observer list" else return nsnull;
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
nsDeque* CObserverService::GetObserversForTag(eHTMLTags aTag) {
|
||||||
if(aTag <= NS_HTML_TAG_MAX)
|
if(aTag <= NS_HTML_TAG_MAX)
|
||||||
return mObservers[aTag];
|
return mObservers[aTag];
|
||||||
return nsnull;
|
return nsnull;
|
||||||
|
|
|
@ -38,6 +38,8 @@
|
||||||
#include "nsString.h"
|
#include "nsString.h"
|
||||||
#include "nsIElementObserver.h"
|
#include "nsIElementObserver.h"
|
||||||
|
|
||||||
|
class nsIParserNode;
|
||||||
|
|
||||||
/***************************************************************
|
/***************************************************************
|
||||||
Before digging into the NavDTD, we'll define a helper
|
Before digging into the NavDTD, we'll define a helper
|
||||||
class called CTagStack.
|
class called CTagStack.
|
||||||
|
@ -242,16 +244,19 @@ struct CRCStruct {
|
||||||
might be nice to use a more dynamic approach that would permit observers to
|
might be nice to use a more dynamic approach that would permit observers to
|
||||||
come and go on a document basis.
|
come and go on a document basis.
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
class CObserverDictionary {
|
class CObserverService {
|
||||||
public:
|
public:
|
||||||
CObserverDictionary();
|
CObserverService();
|
||||||
~CObserverDictionary();
|
~CObserverService();
|
||||||
|
|
||||||
void RegisterObservers(nsString& aTopicList);
|
|
||||||
void UnregisterObservers();
|
|
||||||
nsDeque* GetObserversForTag(eHTMLTags aTag);
|
nsDeque* GetObserversForTag(eHTMLTags aTag);
|
||||||
|
nsresult Notify(eHTMLTags aTag,nsIParserNode& aNode,
|
||||||
|
PRUint32 aUniqueID, nsIDTD* aDTD,
|
||||||
|
nsAutoString& aCharsetValue,nsCharsetSource& aCharsetSource) ;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
void RegisterObservers(nsString& aTopicList);
|
||||||
|
void UnregisterObservers();
|
||||||
nsDeque* mObservers[NS_HTML_TAG_MAX + 1];
|
nsDeque* mObservers[NS_HTML_TAG_MAX + 1];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -223,10 +223,6 @@ nsresult CStartToken::Consume(PRUnichar aChar, nsScanner& aScanner) {
|
||||||
nsresult result=aScanner.ReadWhile(mTextValue,GetIdentChars(),PR_TRUE,PR_FALSE);
|
nsresult result=aScanner.ReadWhile(mTextValue,GetIdentChars(),PR_TRUE,PR_FALSE);
|
||||||
mTypeID = nsHTMLTags::LookupTag(mTextValue);
|
mTypeID = nsHTMLTags::LookupTag(mTextValue);
|
||||||
|
|
||||||
if(eHTMLTag_image==mTypeID){
|
|
||||||
mTypeID=eHTMLTag_img;
|
|
||||||
}
|
|
||||||
|
|
||||||
//Good. Now, let's skip whitespace after the identifier,
|
//Good. Now, let's skip whitespace after the identifier,
|
||||||
//and see if the next char is ">". If so, we have a complete
|
//and see if the next char is ">". If so, we have a complete
|
||||||
//tag without attributes.
|
//tag without attributes.
|
||||||
|
@ -507,7 +503,6 @@ nsresult CTextToken::ConsumeUntil(PRUnichar aChar,PRBool aIgnoreComments,nsScann
|
||||||
//target endtag, or the start of another comment.
|
//target endtag, or the start of another comment.
|
||||||
|
|
||||||
static nsAutoString theWhitespace2("\b\t ");
|
static nsAutoString theWhitespace2("\b\t ");
|
||||||
static nsAutoString theTerminals("\"\'<");
|
|
||||||
|
|
||||||
PRInt32 termStrLen=aTerminalString.Length();
|
PRInt32 termStrLen=aTerminalString.Length();
|
||||||
while((!done) && (NS_OK==result)) {
|
while((!done) && (NS_OK==result)) {
|
||||||
|
@ -523,9 +518,7 @@ nsresult CTextToken::ConsumeUntil(PRUnichar aChar,PRBool aIgnoreComments,nsScann
|
||||||
result=theComment.Consume(aChar,aScanner);
|
result=theComment.Consume(aChar,aScanner);
|
||||||
if(NS_OK==result) {
|
if(NS_OK==result) {
|
||||||
//result=aScanner.SkipWhitespace();
|
//result=aScanner.SkipWhitespace();
|
||||||
//temp.Append("<!");
|
|
||||||
mTextValue.Append(theComment.GetStringValueXXX());
|
mTextValue.Append(theComment.GetStringValueXXX());
|
||||||
//temp.Append(">");
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
//read a tag...
|
//read a tag...
|
||||||
|
@ -534,15 +527,6 @@ nsresult CTextToken::ConsumeUntil(PRUnichar aChar,PRBool aIgnoreComments,nsScann
|
||||||
result=aScanner.ReadUntil(mTextValue,kGreaterThan,PR_TRUE);
|
result=aScanner.ReadUntil(mTextValue,kGreaterThan,PR_TRUE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if((NS_OK==result) && ((kQuote==aChar) || kApostrophe==aChar)) {
|
|
||||||
static nsAutoString theEndings("\n\"\'");
|
|
||||||
mTextValue += aChar;
|
|
||||||
result=aScanner.ReadUntil(mTextValue,theEndings,PR_TRUE,PR_FALSE);
|
|
||||||
if(result==NS_OK) {
|
|
||||||
result=aScanner.GetChar(aChar);
|
|
||||||
if(result==NS_OK) mTextValue += aChar; // consume the character that stopped the scan
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if(0<=theWhitespace2.BinarySearch(aChar)) {
|
else if(0<=theWhitespace2.BinarySearch(aChar)) {
|
||||||
static CWhitespaceToken theWS;
|
static CWhitespaceToken theWS;
|
||||||
result=theWS.Consume(aChar,aScanner);
|
result=theWS.Consume(aChar,aScanner);
|
||||||
|
@ -552,7 +536,7 @@ nsresult CTextToken::ConsumeUntil(PRUnichar aChar,PRBool aIgnoreComments,nsScann
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
mTextValue+=aChar;
|
mTextValue+=aChar;
|
||||||
result=aScanner.ReadUntil(mTextValue,theTerminals,PR_TRUE,PR_FALSE);
|
result=aScanner.ReadUntil(mTextValue,kLessThan,PR_FALSE);
|
||||||
}
|
}
|
||||||
mTextValue.Right(theRight,termStrLen+10); //first, get a wad of chars from the temp string
|
mTextValue.Right(theRight,termStrLen+10); //first, get a wad of chars from the temp string
|
||||||
rpos=theRight.RFindChar('<'); //now scan for the '<'
|
rpos=theRight.RFindChar('<'); //now scan for the '<'
|
||||||
|
@ -560,8 +544,8 @@ nsresult CTextToken::ConsumeUntil(PRUnichar aChar,PRBool aIgnoreComments,nsScann
|
||||||
rpos=theRight.RFind(aTerminalString,PR_TRUE);
|
rpos=theRight.RFind(aTerminalString,PR_TRUE);
|
||||||
done=PRBool(-1<rpos);
|
done=PRBool(-1<rpos);
|
||||||
} //while
|
} //while
|
||||||
int len=mTextValue.Length();
|
|
||||||
if(NS_SUCCEEDED(result)) {
|
if(NS_SUCCEEDED(result)) {
|
||||||
|
int len=mTextValue.Length();
|
||||||
mTextValue.Truncate(len-(theRight.Length()-rpos));
|
mTextValue.Truncate(len-(theRight.Length()-rpos));
|
||||||
|
|
||||||
// Make aTerminalString contain the name of the end tag ** as seen in **
|
// Make aTerminalString contain the name of the end tag ** as seen in **
|
||||||
|
|
|
@ -287,7 +287,7 @@ friend class CTokenHandler;
|
||||||
* @param
|
* @param
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
CObserverDictionary& GetObserverDictionary(void) { return mObserverDictionary; }
|
CObserverService& GetObserverService(void) { return mObserverService; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
|
@ -379,7 +379,7 @@ protected:
|
||||||
nsString mCharset;
|
nsString mCharset;
|
||||||
nsCharsetSource mCharsetSource;
|
nsCharsetSource mCharsetSource;
|
||||||
nsresult mInternalState;
|
nsresult mInternalState;
|
||||||
CObserverDictionary mObserverDictionary;
|
CObserverService mObserverService;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -436,28 +436,6 @@ PRBool CWellFormedDTD::IsContainer(PRInt32 aTag) const{
|
||||||
return result;
|
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,30);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
@ -574,22 +552,6 @@ nsresult CWellFormedDTD::HandleProcessingInstructionToken(CToken* aToken) {
|
||||||
nsresult result=NS_OK;
|
nsresult result=NS_OK;
|
||||||
|
|
||||||
nsCParserNode theNode((CHTMLToken*)aToken,mLineNumber,mTokenizer->GetTokenRecycler());
|
nsCParserNode theNode((CHTMLToken*)aToken,mLineNumber,mTokenizer->GetTokenRecycler());
|
||||||
char thePI[30]={0};
|
|
||||||
nsString& thePIString = aToken->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)? mSink->AddProcessingInstruction(theNode):NS_OK;
|
result=(mSink)? mSink->AddProcessingInstruction(theNode):NS_OK;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1079,90 +1079,58 @@ nsresult CNavDTD::WillHandleStartTag(CToken* aToken,eHTMLTags aTag,nsCParserNode
|
||||||
result=CollectSkippedContent(aNode,theAttrCount);
|
result=CollectSkippedContent(aNode,theAttrCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**********************************************************
|
if(mParser) {
|
||||||
THIS WILL ULTIMATELY BECOME THE REAL OBSERVER API...
|
nsAutoString charsetValue;
|
||||||
**********************************************************/
|
nsCharsetSource charsetSource;
|
||||||
nsDeque* theDeque= (mParser && aTag != eHTMLTag_unknown)? (mParser->GetObserverDictionary()).GetObserversForTag(aTag):nsnull;
|
mParser->GetDocumentCharset(charsetValue,charsetSource);
|
||||||
if(theDeque){
|
CParserContext* pc=mParser->PeekContext();
|
||||||
PRUint32 theDequeSize=theDeque->GetSize();
|
void* theDocID=(pc) ? pc->mKey : 0;
|
||||||
if(0<theDequeSize){
|
result=(mParser->GetObserverService()).Notify(aTag,aNode,(PRUint32)theDocID,this,charsetValue,charsetSource);
|
||||||
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++;
|
|
||||||
}
|
|
||||||
nsAutoString theTagStr(nsHTMLTags::GetStringValue(aTag));
|
|
||||||
CParserContext* pc=mParser->PeekContext();
|
|
||||||
void* theDocID=(pc) ? pc-> mKey : 0;
|
|
||||||
nsObserverNotifier theNotifier(theTagStr.GetUnicode(),(PRUint32)theDocID,index,theKeys,theValues);
|
|
||||||
theDeque->FirstThat(theNotifier);
|
|
||||||
result=theNotifier.mResult;
|
|
||||||
}//if
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if(eHTMLTag_meta==aTag) {
|
|
||||||
PRInt32 theCount=aNode.GetAttributeCount();
|
|
||||||
if(1<theCount){
|
|
||||||
|
|
||||||
const nsString& theKey=aNode.GetKeyAt(0);
|
|
||||||
if(theKey.EqualsIgnoreCase("NAME")) {
|
|
||||||
const nsString& theValue1=aNode.GetValueAt(0);
|
|
||||||
if(theValue1.EqualsIgnoreCase("\"CRC\"")) {
|
|
||||||
const nsString& theKey2=aNode.GetKeyAt(1);
|
|
||||||
if(theKey2.EqualsIgnoreCase("CONTENT")) {
|
|
||||||
const nsString& theValue2=aNode.GetValueAt(1);
|
|
||||||
PRInt32 err=0;
|
|
||||||
mExpectedCRC32=theValue2.ToInteger(&err);
|
|
||||||
} //if
|
|
||||||
} //if
|
|
||||||
} //else
|
|
||||||
|
|
||||||
} //if
|
|
||||||
}//if
|
|
||||||
|
|
||||||
if(NS_OK==result) {
|
|
||||||
result=gHTMLElements[aTag].HasSpecialProperty(kDiscardTag) ? 1 : NS_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
PRBool isHeadChild=gHTMLElements[eHTMLTag_head].IsChildOfHead(aTag);
|
|
||||||
|
|
||||||
//this code is here to make sure the head is closed before we deal
|
if(NS_SUCCEEDED(result)) {
|
||||||
//with any tags that don't belong in the head.
|
if(eHTMLTag_meta==aTag) {
|
||||||
if(NS_OK==result) {
|
PRInt32 theCount=aNode.GetAttributeCount();
|
||||||
if(mHasOpenHead){
|
if(1<theCount){
|
||||||
static eHTMLTags skip2[]={eHTMLTag_newline,eHTMLTag_whitespace};
|
|
||||||
if(!FindTagInSet(aTag,skip2,sizeof(skip2)/sizeof(eHTMLTag_unknown))){
|
const nsString& theKey=aNode.GetKeyAt(0);
|
||||||
if(!isHeadChild){
|
if(theKey.EqualsIgnoreCase("NAME")) {
|
||||||
CEndToken theToken(eHTMLTag_head);
|
const nsString& theValue1=aNode.GetValueAt(0);
|
||||||
nsCParserNode theNode(&theToken,mLineNumber);
|
if(theValue1.EqualsIgnoreCase("\"CRC\"")) {
|
||||||
result=CloseHead(theNode);
|
const nsString& theKey2=aNode.GetKeyAt(1);
|
||||||
|
if(theKey2.EqualsIgnoreCase("CONTENT")) {
|
||||||
|
const nsString& theValue2=aNode.GetValueAt(1);
|
||||||
|
PRInt32 err=0;
|
||||||
|
mExpectedCRC32=theValue2.ToInteger(&err);
|
||||||
|
} //if
|
||||||
|
} //if
|
||||||
|
} //else
|
||||||
|
|
||||||
|
} //if
|
||||||
|
}//if
|
||||||
|
|
||||||
|
if(NS_OK==result) {
|
||||||
|
result=gHTMLElements[aTag].HasSpecialProperty(kDiscardTag) ? 1 : NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
PRBool isHeadChild=gHTMLElements[eHTMLTag_head].IsChildOfHead(aTag);
|
||||||
|
|
||||||
|
//this code is here to make sure the head is closed before we deal
|
||||||
|
//with any tags that don't belong in the head.
|
||||||
|
if(NS_OK==result) {
|
||||||
|
if(mHasOpenHead){
|
||||||
|
static eHTMLTags skip2[]={eHTMLTag_newline,eHTMLTag_whitespace};
|
||||||
|
if(!FindTagInSet(aTag,skip2,sizeof(skip2)/sizeof(eHTMLTag_unknown))){
|
||||||
|
if(!isHeadChild){
|
||||||
|
CEndToken theToken(eHTMLTag_head);
|
||||||
|
nsCParserNode theNode(&theToken,mLineNumber);
|
||||||
|
result=CloseHead(theNode);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1302,6 +1270,11 @@ nsresult CNavDTD::HandleStartToken(CToken* aToken) {
|
||||||
result=mSink->AddLeaf(*theNode);
|
result=mSink->AddLeaf(*theNode);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case eHTMLTag_image:
|
||||||
|
aToken->SetTypeID(theChildTag=eHTMLTag_img);
|
||||||
|
result=HandleDefaultStartToken(aToken,theChildTag,*theNode);
|
||||||
|
break;
|
||||||
|
|
||||||
case eHTMLTag_userdefined:
|
case eHTMLTag_userdefined:
|
||||||
break; //drop them on the floor for now...
|
break; //drop them on the floor for now...
|
||||||
|
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
|
|
||||||
#include "nsDTDUtils.h"
|
#include "nsDTDUtils.h"
|
||||||
#include "CNavDTD.h"
|
#include "CNavDTD.h"
|
||||||
|
#include "nsIParserNode.h"
|
||||||
|
|
||||||
#include "nsIObserverService.h"
|
#include "nsIObserverService.h"
|
||||||
#include "nsIServiceManager.h"
|
#include "nsIServiceManager.h"
|
||||||
|
@ -640,7 +641,7 @@ PRUint32 AccumulateCRC(PRUint32 crc_accum, char *data_blk_ptr, int data_blk_size
|
||||||
come and go on a document basis.
|
come and go on a document basis.
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
||||||
CObserverDictionary::CObserverDictionary() {
|
CObserverService::CObserverService() {
|
||||||
|
|
||||||
nsCRT::zero(mObservers,sizeof(mObservers));
|
nsCRT::zero(mObservers,sizeof(mObservers));
|
||||||
|
|
||||||
|
@ -652,7 +653,7 @@ CObserverDictionary::CObserverDictionary() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CObserverDictionary::~CObserverDictionary() {
|
CObserverService::~CObserverService() {
|
||||||
UnregisterObservers();
|
UnregisterObservers();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -668,19 +669,34 @@ public:
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
void CObserverDictionary::UnregisterObservers() {
|
/**
|
||||||
|
* Release observers and empty the observer array.
|
||||||
|
*
|
||||||
|
* @update harishd 08/29/99
|
||||||
|
* @param
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
|
||||||
|
void CObserverService::UnregisterObservers() {
|
||||||
int theIndex=0;
|
int theIndex=0;
|
||||||
nsObserverReleaser theReleaser;
|
nsObserverReleaser theReleaser;
|
||||||
for(theIndex=0;theIndex<=NS_HTML_TAG_MAX;theIndex++){
|
for(theIndex=0;theIndex<=NS_HTML_TAG_MAX;theIndex++){
|
||||||
if(mObservers[theIndex]){
|
if(mObservers[theIndex]){
|
||||||
//nsIElementObserver* theElementObserver=0;
|
|
||||||
mObservers[theIndex]->ForEach(theReleaser);
|
mObservers[theIndex]->ForEach(theReleaser);
|
||||||
delete mObservers[theIndex];
|
delete mObservers[theIndex];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CObserverDictionary::RegisterObservers(nsString& aTopic) {
|
/**
|
||||||
|
* This method will maintain lists of observers registered for specific tags.
|
||||||
|
*
|
||||||
|
* @update harishd 08/29/99
|
||||||
|
* @param aTopic - The topic under which observers register for.
|
||||||
|
* @return if SUCCESS return NS_OK else return ERROR code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void CObserverService::RegisterObservers(nsString& aTopic) {
|
||||||
nsresult result = NS_OK;
|
nsresult result = NS_OK;
|
||||||
nsIObserverService* theObserverService = nsnull;
|
nsIObserverService* theObserverService = nsnull;
|
||||||
result = nsServiceManager::GetService(NS_OBSERVERSERVICE_PROGID, nsIObserverService::GetIID(),
|
result = nsServiceManager::GetService(NS_OBSERVERSERVICE_PROGID, nsIObserverService::GetIID(),
|
||||||
|
@ -703,22 +719,16 @@ void CObserverDictionary::RegisterObservers(nsString& aTopic) {
|
||||||
PRUint32 theTagIndex = 0;
|
PRUint32 theTagIndex = 0;
|
||||||
theTagStr = theElementObserver->GetTagNameAt(theTagIndex);
|
theTagStr = theElementObserver->GetTagNameAt(theTagIndex);
|
||||||
while (theTagStr != nsnull) {
|
while (theTagStr != nsnull) {
|
||||||
// XXX - HACK - Hardcoding PI for simplification. PI handling should not
|
eHTMLTags theTag = nsHTMLTags::LookupTag(nsCAutoString(theTagStr));
|
||||||
// happen along with ** tags **. For now the specific PI, ?xml, is treated
|
|
||||||
// as an unknown tag in the dictionary!!!!
|
|
||||||
eHTMLTags theTag = (nsCRT::strcmp(theTagStr,"?xml") == 0) ? eHTMLTag_unknown :
|
|
||||||
nsHTMLTags::LookupTag(nsCAutoString(theTagStr));
|
|
||||||
if((eHTMLTag_userdefined!=theTag) && (theTag <= NS_HTML_TAG_MAX)){
|
if((eHTMLTag_userdefined!=theTag) && (theTag <= NS_HTML_TAG_MAX)){
|
||||||
if(mObservers[theTag] == nsnull) {
|
if(mObservers[theTag] == nsnull) {
|
||||||
mObservers[theTag] = new nsDeque(0);
|
mObservers[theTag] = new nsDeque(0);
|
||||||
}
|
}
|
||||||
NS_ADDREF(theElementObserver);
|
|
||||||
mObservers[theTag]->Push(theElementObserver);
|
mObservers[theTag]->Push(theElementObserver);
|
||||||
}
|
}
|
||||||
theTagIndex++;
|
theTagIndex++;
|
||||||
theTagStr = theElementObserver->GetTagNameAt(theTagIndex);
|
theTagStr = theElementObserver->GetTagNameAt(theTagIndex);
|
||||||
}
|
}
|
||||||
NS_RELEASE(theElementObserver);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -726,7 +736,69 @@ void CObserverDictionary::RegisterObservers(nsString& aTopic) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
nsDeque* CObserverDictionary::GetObserversForTag(eHTMLTags aTag) {
|
/**
|
||||||
|
* This method will notify observers registered for specific tags.
|
||||||
|
*
|
||||||
|
* @update harishd 08/29/99
|
||||||
|
* @param aTag - The tag for which observers could be waiting for.
|
||||||
|
* @param aNode -
|
||||||
|
* @param aUniqueID - The document ID.
|
||||||
|
* @param aDTD - The current DTD.
|
||||||
|
* @param aCharsetValue -
|
||||||
|
* @param aCharsetSource -
|
||||||
|
* @return if SUCCESS return NS_OK else return ERROR code.
|
||||||
|
*/
|
||||||
|
nsresult CObserverService::Notify(eHTMLTags aTag,nsIParserNode& aNode,PRUint32 aUniqueID, nsIDTD* aDTD,
|
||||||
|
nsAutoString& aCharsetValue,nsCharsetSource& aCharsetSource) {
|
||||||
|
nsresult result=NS_OK;
|
||||||
|
nsDeque* theDeque=GetObserversForTag(aTag);
|
||||||
|
if(theDeque){
|
||||||
|
PRInt32 theAttrCount =aNode.GetAttributeCount();
|
||||||
|
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 theCharsetKey("charset");
|
||||||
|
nsAutoString theSourceKey("charsetSource");
|
||||||
|
nsAutoString intValue;
|
||||||
|
// Add pseudo attribute in the end
|
||||||
|
if(index < 50) {
|
||||||
|
theKeys[index]=theCharsetKey.GetUnicode();
|
||||||
|
theValues[index] = aCharsetValue.GetUnicode();
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
if(index < 50) {
|
||||||
|
theKeys[index]=theSourceKey.GetUnicode();
|
||||||
|
PRInt32 sourceInt = aCharsetSource;
|
||||||
|
intValue.Append(sourceInt,10);
|
||||||
|
theValues[index] = intValue.GetUnicode();
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
nsAutoString theTagStr(nsHTMLTags::GetStringValue(aTag));
|
||||||
|
nsObserverNotifier theNotifier(theTagStr.GetUnicode(),aUniqueID,index,theKeys,theValues);
|
||||||
|
theDeque->FirstThat(theNotifier);
|
||||||
|
result=theNotifier.mResult;
|
||||||
|
}//if
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method will look for the list of observers registered for
|
||||||
|
* a specific tag.
|
||||||
|
*
|
||||||
|
* @update harishd 08/29/99
|
||||||
|
* @param aTag - The tag for which observers could be waiting for.
|
||||||
|
* @return if FOUND return "observer list" else return nsnull;
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
nsDeque* CObserverService::GetObserversForTag(eHTMLTags aTag) {
|
||||||
if(aTag <= NS_HTML_TAG_MAX)
|
if(aTag <= NS_HTML_TAG_MAX)
|
||||||
return mObservers[aTag];
|
return mObservers[aTag];
|
||||||
return nsnull;
|
return nsnull;
|
||||||
|
|
|
@ -38,6 +38,8 @@
|
||||||
#include "nsString.h"
|
#include "nsString.h"
|
||||||
#include "nsIElementObserver.h"
|
#include "nsIElementObserver.h"
|
||||||
|
|
||||||
|
class nsIParserNode;
|
||||||
|
|
||||||
/***************************************************************
|
/***************************************************************
|
||||||
Before digging into the NavDTD, we'll define a helper
|
Before digging into the NavDTD, we'll define a helper
|
||||||
class called CTagStack.
|
class called CTagStack.
|
||||||
|
@ -242,16 +244,19 @@ struct CRCStruct {
|
||||||
might be nice to use a more dynamic approach that would permit observers to
|
might be nice to use a more dynamic approach that would permit observers to
|
||||||
come and go on a document basis.
|
come and go on a document basis.
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
class CObserverDictionary {
|
class CObserverService {
|
||||||
public:
|
public:
|
||||||
CObserverDictionary();
|
CObserverService();
|
||||||
~CObserverDictionary();
|
~CObserverService();
|
||||||
|
|
||||||
void RegisterObservers(nsString& aTopicList);
|
|
||||||
void UnregisterObservers();
|
|
||||||
nsDeque* GetObserversForTag(eHTMLTags aTag);
|
nsDeque* GetObserversForTag(eHTMLTags aTag);
|
||||||
|
nsresult Notify(eHTMLTags aTag,nsIParserNode& aNode,
|
||||||
|
PRUint32 aUniqueID, nsIDTD* aDTD,
|
||||||
|
nsAutoString& aCharsetValue,nsCharsetSource& aCharsetSource) ;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
void RegisterObservers(nsString& aTopicList);
|
||||||
|
void UnregisterObservers();
|
||||||
nsDeque* mObservers[NS_HTML_TAG_MAX + 1];
|
nsDeque* mObservers[NS_HTML_TAG_MAX + 1];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -223,10 +223,6 @@ nsresult CStartToken::Consume(PRUnichar aChar, nsScanner& aScanner) {
|
||||||
nsresult result=aScanner.ReadWhile(mTextValue,GetIdentChars(),PR_TRUE,PR_FALSE);
|
nsresult result=aScanner.ReadWhile(mTextValue,GetIdentChars(),PR_TRUE,PR_FALSE);
|
||||||
mTypeID = nsHTMLTags::LookupTag(mTextValue);
|
mTypeID = nsHTMLTags::LookupTag(mTextValue);
|
||||||
|
|
||||||
if(eHTMLTag_image==mTypeID){
|
|
||||||
mTypeID=eHTMLTag_img;
|
|
||||||
}
|
|
||||||
|
|
||||||
//Good. Now, let's skip whitespace after the identifier,
|
//Good. Now, let's skip whitespace after the identifier,
|
||||||
//and see if the next char is ">". If so, we have a complete
|
//and see if the next char is ">". If so, we have a complete
|
||||||
//tag without attributes.
|
//tag without attributes.
|
||||||
|
@ -507,7 +503,6 @@ nsresult CTextToken::ConsumeUntil(PRUnichar aChar,PRBool aIgnoreComments,nsScann
|
||||||
//target endtag, or the start of another comment.
|
//target endtag, or the start of another comment.
|
||||||
|
|
||||||
static nsAutoString theWhitespace2("\b\t ");
|
static nsAutoString theWhitespace2("\b\t ");
|
||||||
static nsAutoString theTerminals("\"\'<");
|
|
||||||
|
|
||||||
PRInt32 termStrLen=aTerminalString.Length();
|
PRInt32 termStrLen=aTerminalString.Length();
|
||||||
while((!done) && (NS_OK==result)) {
|
while((!done) && (NS_OK==result)) {
|
||||||
|
@ -523,9 +518,7 @@ nsresult CTextToken::ConsumeUntil(PRUnichar aChar,PRBool aIgnoreComments,nsScann
|
||||||
result=theComment.Consume(aChar,aScanner);
|
result=theComment.Consume(aChar,aScanner);
|
||||||
if(NS_OK==result) {
|
if(NS_OK==result) {
|
||||||
//result=aScanner.SkipWhitespace();
|
//result=aScanner.SkipWhitespace();
|
||||||
//temp.Append("<!");
|
|
||||||
mTextValue.Append(theComment.GetStringValueXXX());
|
mTextValue.Append(theComment.GetStringValueXXX());
|
||||||
//temp.Append(">");
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
//read a tag...
|
//read a tag...
|
||||||
|
@ -534,15 +527,6 @@ nsresult CTextToken::ConsumeUntil(PRUnichar aChar,PRBool aIgnoreComments,nsScann
|
||||||
result=aScanner.ReadUntil(mTextValue,kGreaterThan,PR_TRUE);
|
result=aScanner.ReadUntil(mTextValue,kGreaterThan,PR_TRUE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if((NS_OK==result) && ((kQuote==aChar) || kApostrophe==aChar)) {
|
|
||||||
static nsAutoString theEndings("\n\"\'");
|
|
||||||
mTextValue += aChar;
|
|
||||||
result=aScanner.ReadUntil(mTextValue,theEndings,PR_TRUE,PR_FALSE);
|
|
||||||
if(result==NS_OK) {
|
|
||||||
result=aScanner.GetChar(aChar);
|
|
||||||
if(result==NS_OK) mTextValue += aChar; // consume the character that stopped the scan
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if(0<=theWhitespace2.BinarySearch(aChar)) {
|
else if(0<=theWhitespace2.BinarySearch(aChar)) {
|
||||||
static CWhitespaceToken theWS;
|
static CWhitespaceToken theWS;
|
||||||
result=theWS.Consume(aChar,aScanner);
|
result=theWS.Consume(aChar,aScanner);
|
||||||
|
@ -552,7 +536,7 @@ nsresult CTextToken::ConsumeUntil(PRUnichar aChar,PRBool aIgnoreComments,nsScann
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
mTextValue+=aChar;
|
mTextValue+=aChar;
|
||||||
result=aScanner.ReadUntil(mTextValue,theTerminals,PR_TRUE,PR_FALSE);
|
result=aScanner.ReadUntil(mTextValue,kLessThan,PR_FALSE);
|
||||||
}
|
}
|
||||||
mTextValue.Right(theRight,termStrLen+10); //first, get a wad of chars from the temp string
|
mTextValue.Right(theRight,termStrLen+10); //first, get a wad of chars from the temp string
|
||||||
rpos=theRight.RFindChar('<'); //now scan for the '<'
|
rpos=theRight.RFindChar('<'); //now scan for the '<'
|
||||||
|
@ -560,8 +544,8 @@ nsresult CTextToken::ConsumeUntil(PRUnichar aChar,PRBool aIgnoreComments,nsScann
|
||||||
rpos=theRight.RFind(aTerminalString,PR_TRUE);
|
rpos=theRight.RFind(aTerminalString,PR_TRUE);
|
||||||
done=PRBool(-1<rpos);
|
done=PRBool(-1<rpos);
|
||||||
} //while
|
} //while
|
||||||
int len=mTextValue.Length();
|
|
||||||
if(NS_SUCCEEDED(result)) {
|
if(NS_SUCCEEDED(result)) {
|
||||||
|
int len=mTextValue.Length();
|
||||||
mTextValue.Truncate(len-(theRight.Length()-rpos));
|
mTextValue.Truncate(len-(theRight.Length()-rpos));
|
||||||
|
|
||||||
// Make aTerminalString contain the name of the end tag ** as seen in **
|
// Make aTerminalString contain the name of the end tag ** as seen in **
|
||||||
|
|
|
@ -287,7 +287,7 @@ friend class CTokenHandler;
|
||||||
* @param
|
* @param
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
CObserverDictionary& GetObserverDictionary(void) { return mObserverDictionary; }
|
CObserverService& GetObserverService(void) { return mObserverService; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
|
@ -379,7 +379,7 @@ protected:
|
||||||
nsString mCharset;
|
nsString mCharset;
|
||||||
nsCharsetSource mCharsetSource;
|
nsCharsetSource mCharsetSource;
|
||||||
nsresult mInternalState;
|
nsresult mInternalState;
|
||||||
CObserverDictionary mObserverDictionary;
|
CObserverService mObserverService;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -436,28 +436,6 @@ PRBool CWellFormedDTD::IsContainer(PRInt32 aTag) const{
|
||||||
return result;
|
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,30);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
@ -574,22 +552,6 @@ nsresult CWellFormedDTD::HandleProcessingInstructionToken(CToken* aToken) {
|
||||||
nsresult result=NS_OK;
|
nsresult result=NS_OK;
|
||||||
|
|
||||||
nsCParserNode theNode((CHTMLToken*)aToken,mLineNumber,mTokenizer->GetTokenRecycler());
|
nsCParserNode theNode((CHTMLToken*)aToken,mLineNumber,mTokenizer->GetTokenRecycler());
|
||||||
char thePI[30]={0};
|
|
||||||
nsString& thePIString = aToken->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)? mSink->AddProcessingInstruction(theNode):NS_OK;
|
result=(mSink)? mSink->AddProcessingInstruction(theNode):NS_OK;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
Загрузка…
Ссылка в новой задаче