96364 - Register html tag observers directly to parser service rather than nsObserverService. Doing so, reduces a lot of overhead. Also, the observers are now notified via sink. This eliminates the need for parser bundle.

r=dp,shanjian,sfraser, sr=rpotts.


git-svn-id: svn://10.0.0.236/trunk@104152 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
harishd%netscape.com
2001-09-28 23:08:17 +00:00
parent 3c1b9e9fad
commit 1c4e4c74ec
57 changed files with 541 additions and 1544 deletions

View File

@@ -59,7 +59,6 @@
#include "nsTagHandler.h"
#include "nsHTMLTokenizer.h"
#include "nsTime.h"
#include "nsIElementObserver.h"
#include "nsViewSourceHTML.h"
#include "nsParserNode.h"
#include "nsHTMLEntities.h"
@@ -189,7 +188,7 @@ CNavDTD::CNavDTD() : nsIDTD(),
mLineNumber(1)
{
NS_INIT_REFCNT();
mBodyContext=new nsDTDContext();
#ifdef RICKG_DEBUG
@@ -198,7 +197,6 @@ CNavDTD::CNavDTD() : nsIDTD(),
nsHTMLElement::DebugDumpMembership("c:/temp/membership.out");
nsHTMLElement::DebugDumpContainType("c:/temp/ctnrules.out");
#endif
}
/**
@@ -1377,13 +1375,8 @@ nsresult CNavDTD::WillHandleStartTag(CToken* aToken,eHTMLTags aTag,nsIParserNode
STOP_TIMER()
MOZ_TIMER_DEBUGLOG(("Stop: Parse Time: CNavDTD::WillHandleStartTag(), this=%p\n", this));
if(mParser) {
CObserverService* theService=mParser->GetObserverService();
if(theService) {
const nsISupportsParserBundle* bundle=mParser->GetParserBundle();
result=theService->Notify(aTag,aNode,(void*)bundle, mMimeType, mParser);
}
if (aTag <= NS_HTML_TAG_MAX) {
result = mSink->NotifyTagObservers(&aNode);
}
MOZ_TIMER_DEBUGLOG(("Start: Parse Time: CNavDTD::WillHandleStartTag(), this=%p\n", this));

View File

@@ -57,7 +57,6 @@
#include "nsTagHandler.h"
#include "nsHTMLTokenizer.h"
#include "nsTime.h"
#include "nsIElementObserver.h"
#include "nsViewSourceHTML.h"
#include "nsParserNode.h"
#include "nsHTMLEntities.h"
@@ -70,7 +69,7 @@ static NS_DEFINE_IID(kIHTMLContentSinkIID, NS_IHTML_CONTENT_SINK_IID);
static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
static NS_DEFINE_IID(kIDTDIID, NS_IDTD_IID);
static NS_DEFINE_IID(kClassIID, NS_IOTHERHTML_DTD_IID);
static NS_DEFINE_IID(kParserServiceCID, NS_PARSERSERVICE_CID);
static char* kVerificationDir = "c:/temp";
@@ -640,12 +639,7 @@ nsresult COtherDTD::WillHandleStartTag(CToken* aToken,eHTMLTags aTag,nsIParserNo
default:
break;
}
CObserverService* theService=mParser->GetObserverService();
if(theService) {
const nsISupportsParserBundle* bundle=mParser->GetParserBundle();
result=theService->Notify(aTag,aNode,(void*)bundle, NS_ConvertASCIItoUCS2(kHTMLTextContentType), mParser);
}
mSink->NotifyTagObservers(&aNode);
}
MOZ_TIMER_DEBUGLOG(("Start: Parse Time: COtherDTD::WillHandleStartTag(), this=%p\n", this));

View File

@@ -68,6 +68,7 @@ CPPSRCS = \
nsHTMLTokens.cpp \
nsParser.cpp \
CParserContext.cpp \
nsParserService.cpp \
nsParserModule.cpp \
nsParserNode.cpp \
nsScanner.cpp \

View File

@@ -62,6 +62,7 @@ CPPSRCS = \
nsToken.cpp \
nsWellFormedDTD.cpp \
nsViewSourceHTML.cpp\
nsParserService.cpp \
nsParserModule.cpp \
nsParserMsgUtils.cpp \
!ifdef MOZ_DEBUG
@@ -87,6 +88,7 @@ CPP_OBJS = \
.\$(OBJDIR)\nsToken.obj \
.\$(OBJDIR)\nsWellFormedDTD.obj \
.\$(OBJDIR)\nsViewSourceHTML.obj\
.\$(OBJDIR)\nsParserService.obj \
.\$(OBJDIR)\nsParserModule.obj \
.\$(OBJDIR)\nsParserMsgUtils.obj \
!ifdef MOZ_DEBUG

View File

@@ -42,18 +42,14 @@
#include "CNavDTD.h"
#include "nsIParserNode.h"
#include "nsParserNode.h"
#include "nsIChannel.h"
#include "nsIServiceManager.h"
nsIObserverService *CObserverService::gObserverService = NULL;
MOZ_DECL_CTOR_COUNTER(nsEntryStack)
MOZ_DECL_CTOR_COUNTER(nsDTDContext)
MOZ_DECL_CTOR_COUNTER(nsTokenAllocator)
MOZ_DECL_CTOR_COUNTER(CNodeRecycler)
MOZ_DECL_CTOR_COUNTER(CObserverService)
/**************************************************************************************
A few notes about how residual style handling is performed:
@@ -1477,313 +1473,131 @@ PRUint32 AccumulateCRC(PRUint32 crc_accum, char *data_blk_ptr, int data_blk_size
return crc_accum;
}
/**************************************************************
Define the nsIElementObserver release class...
**************************************************************/
class nsObserverReleaser: public nsDequeFunctor{
public:
virtual void* operator()(void* anObject) {
nsIElementObserver* theObserver= (nsIElementObserver*)anObject;
NS_RELEASE(theObserver);
return 0;
}
};
/**************************************************************
This defines the topic object used by the observer service.
The observerService uses a list of these, 1 per topic when
registering tags.
**************************************************************/
NS_IMPL_ISUPPORTS1(nsObserverEntry, nsIObserverEntry)
nsObserverTopic::nsObserverTopic(const nsString& aTopic) : mTopic(aTopic) {
nsCRT::zero(mObservers,sizeof(mObservers));
mCharsetKey.AssignWithConversion("charset");
mSourceKey.AssignWithConversion("charsetSource");
mDTDKey.AssignWithConversion("X_COMMAND");
nsObserverEntry::nsObserverEntry(const nsAString& aTopic) : mTopic(aTopic)
{
NS_INIT_ISUPPORTS();
nsCRT::zero(mObservers,sizeof(mObservers));
}
nsObserverTopic::~nsObserverTopic() {
nsObserverReleaser theReleaser;
PRInt32 theIndex=0;
for(theIndex=0;theIndex<=NS_HTML_TAG_MAX;theIndex++){
if(mObservers[theIndex]){
mObservers[theIndex]->ForEach(theReleaser);
delete mObservers[theIndex];
mObservers[theIndex]=0;
nsObserverEntry::~nsObserverEntry() {
for (PRInt32 i = 0; i <= NS_HTML_TAG_MAX; i++){
if (mObservers[i]) {
PRInt32 count = mObservers[i]->Count();
for (PRInt32 j = 0; j < count; j++) {
nsISupports* obs = (nsISupports*)mObservers[i]->ElementAt(j);
NS_IF_RELEASE(obs);
}
delete mObservers[i];
}
}
}
PRBool nsObserverTopic::Matches(const nsString& aString) {
PRBool result=aString.Equals(mTopic);
return result;
}
NS_IMETHODIMP
nsObserverEntry::Notify(nsIParserNode* aNode,
nsIParser* aParser,
nsISupports* aWebShell)
{
NS_ENSURE_ARG_POINTER(aNode);
NS_ENSURE_ARG_POINTER(aParser);
nsDeque* nsObserverTopic::GetObserversForTag(eHTMLTags aTag) {
if(aTag <= NS_HTML_TAG_MAX) {
return mObservers[aTag];
}
return 0;
}
nsresult result = NS_OK;
eHTMLTags theTag = (eHTMLTags)aNode->GetNodeType();
if (theTag <= NS_HTML_TAG_MAX) {
nsVoidArray* theObservers = mObservers[theTag];
if (theObservers) {
nsAutoString theCharsetValue;
nsCharsetSource theCharsetSource;
aParser->GetDocumentCharset(theCharsetValue,theCharsetSource);
void nsObserverTopic::RegisterObserverForTag(nsIElementObserver *anObserver,eHTMLTags aTag) {
if(anObserver) {
if(mObservers[aTag] == nsnull) {
mObservers[aTag] = new nsDeque(0);
}
NS_ADDREF(anObserver);
mObservers[aTag]->Push(anObserver);
}
}
PRInt32 theAttrCount = aNode->GetAttributeCount();
PRInt32 theObserversCount = theObservers->Count();
if (0 < theObserversCount){
nsStringArray keys(theAttrCount+4), values(theAttrCount+4);
/**
* 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 nsObserverTopic::Notify(eHTMLTags aTag,nsIParserNode& aNode,void* aUniqueID,nsIParser* aParser) {
nsresult result=NS_OK;
// XXX this and the following code may be a performance issue.
// Every key and value is copied and added to an voidarray (causing at
// least 2 allocations for mImpl, usually more, plus at least 1 per
// string (total = 2*(keys+3) + 2(or more) array allocations )).
PRInt32 index;
for (index = 0; index < theAttrCount; index++) {
keys.AppendString(aNode->GetKeyAt(index));
values.AppendString(aNode->GetValueAt(index));
}
nsDeque* theObservers=GetObserversForTag(aTag);
if(theObservers){
nsAutoString intValue;
nsAutoString theCharsetValue;
nsCharsetSource theCharsetSource;
aParser->GetDocumentCharset(theCharsetValue,theCharsetSource);
PRInt32 theAttrCount =aNode.GetAttributeCount();
PRInt32 theObserversCount=theObservers->GetSize();
if(0<theObserversCount){
nsStringArray keys(theAttrCount+4),values(theAttrCount+4);
// XXX this and the following code may be a performance issue.
// Every key and value is copied and added to an voidarray (causing at
// least 2 allocations for mImpl, usually more, plus at least 1 per
// string (total = 2*(keys+3) + 2(or more) array allocations )).
PRInt32 index;
for(index=0; index<theAttrCount; index++) {
keys.AppendString(aNode.GetKeyAt(index));
values.AppendString(aNode.GetValueAt(index));
}
nsAutoString intValue;
keys.AppendString(mCharsetKey);
values.AppendString(theCharsetValue);
keys.AppendString(NS_LITERAL_STRING("charset"));
values.AppendString(theCharsetValue);
keys.AppendString(mSourceKey);
intValue.AppendInt(PRInt32(theCharsetSource),10);
values.AppendString(intValue);
keys.AppendString(NS_LITERAL_STRING("charsetSource"));
intValue.AppendInt(PRInt32(theCharsetSource),10);
values.AppendString(intValue);
keys.AppendString(mDTDKey);
values.AppendString(mTopic);
keys.AppendString(NS_LITERAL_STRING("X_COMMAND"));
values.AppendString(NS_LITERAL_STRING("text/html"));
nsAutoString theTagStr; theTagStr.AssignWithConversion(nsHTMLTags::GetStringValue(aTag));
for(index=0;index<theObserversCount;index++) {
nsIElementObserver* observer=NS_STATIC_CAST(nsIElementObserver*,theObservers->ObjectAt(index));
if(observer) {
result=observer->Notify((nsISupports*)aUniqueID,theTagStr.get(),&keys,&values);
if(NS_FAILED(result)) {
break;
nsAutoString theTagStr;
theTagStr.AssignWithConversion(nsHTMLTags::GetStringValue(theTag));
nsCOMPtr<nsIChannel> channel;
aParser->GetChannel(getter_AddRefs(channel));
for (index=0;index<theObserversCount;index++) {
nsIElementObserver* observer = NS_STATIC_CAST(nsIElementObserver*,theObservers->ElementAt(index));
if (observer) {
result = observer->Notify(aWebShell,channel,theTagStr.get(),&keys,&values);
if (NS_FAILED(result)) {
break;
}
}
}
}
}
}//if
}
}
}
return result;
}
PRBool
nsObserverEntry::Matches(const nsAString& aString) {
PRBool result = aString.Equals(mTopic);
return result;
}
/******************************************************************************
This class is used to store ref's to tag observers during the parse phase.
Note that for simplicity, this is a singleton that is constructed in the
CNavDTD and shared for the duration of the application session. Later on it
might be nice to use a more dynamic approach that would permit observers to
come and go on a document basis.
I changed the observerservice to store topics so that we can distinguish
observers by topic. Up till now, they've all just be thrown into the same
observer list, which was wrong. This fixes bug #28825.
******************************************************************************/
nsresult
CObserverService::InitGlobals() {
if (!gObserverService) {
nsresult rv = NS_OK;
nsCOMPtr<nsIObserverService> obs(do_GetService(NS_OBSERVERSERVICE_CONTRACTID,&rv));
if (NS_SUCCEEDED(rv)) {
gObserverService = obs.get();
NS_IF_ADDREF(gObserverService);
nsObserverEntry::AddObserver(nsIElementObserver *aObserver,
eHTMLTags aTag)
{
if (aObserver) {
if (!mObservers[aTag]) {
mObservers[aTag] = new nsAutoVoidArray();
if (!mObservers[aTag]) {
return NS_ERROR_OUT_OF_MEMORY;
}
}
NS_ADDREF(aObserver);
mObservers[aTag]->AppendElement(aObserver);
}
return NS_OK;
}
void
CObserverService::ReleaseGlobals() {
NS_IF_RELEASE(gObserverService);
}
CObserverService::CObserverService() : mTopics(0) {
MOZ_COUNT_CTOR(CObserverService);
nsAutoString theHTMLTopic; theHTMLTopic.AssignWithConversion(kHTMLTextContentType);
RegisterObservers(theHTMLTopic);
nsAutoString theXMLTopic; theXMLTopic.AssignWithConversion(kXMLTextContentType); //use the mimetype for the topic
RegisterObservers(theXMLTopic);
theXMLTopic.AssignWithConversion(kXMLApplicationContentType);
RegisterObservers(theXMLTopic);
theXMLTopic.AssignWithConversion(kXHTMLApplicationContentType);
RegisterObservers(theXMLTopic);
}
CObserverService::~CObserverService() {
MOZ_COUNT_DTOR(CObserverService);
nsObserverTopic *theTopic=(nsObserverTopic*)mTopics.Pop();
while(theTopic) {
delete theTopic;
theTopic=(nsObserverTopic*)mTopics.Pop();
}
}
// XXX This may be more efficient as a HashTable instead of linear search
nsObserverTopic* CObserverService::GetTopic(const nsString& aTopic) {
PRInt32 theIndex=0;
nsObserverTopic *theTopic=(nsObserverTopic*)mTopics.ObjectAt(theIndex++);
while(theTopic) {
if(theTopic->Matches(aTopic))
return theTopic;
theTopic=(nsObserverTopic*)mTopics.ObjectAt(theIndex++);
}
return 0;
}
nsObserverTopic* CObserverService::CreateTopic(const nsString& aTopic) {
nsObserverTopic* theTopic=new nsObserverTopic(aTopic);
mTopics.Push(theTopic);
return theTopic;
}
/**
* This method will maintain lists of observers registered for specific tags.
*
* @update rickg 03.23.2000
* @param aTopic - The topic under which observers register for.
* @return if SUCCESS return NS_OK else return ERROR code.
*/
void CObserverService::RegisterObservers(const nsString& aTopic) {
nsresult result = NS_OK;
if (gObserverService) {
nsIEnumerator* theEnum = nsnull;
result = gObserverService->EnumerateObserverList(aTopic.get(), &theEnum);
if(result == NS_OK) {
nsCOMPtr<nsIElementObserver> theElementObserver;
nsISupports *inst = nsnull;
nsObserverTopic *theTopic=0;
for (theEnum->First(); theEnum->IsDone() != NS_OK; theEnum->Next()) {
result = theEnum->CurrentItem(&inst);
if (NS_SUCCEEDED(result)) {
theElementObserver = do_QueryInterface(inst, &result);
NS_RELEASE(inst);
}
if (result == NS_OK) {
const char* theTagStr = nsnull;
PRUint32 theTagIndex = 0;
theTagStr = theElementObserver->GetTagNameAt(theTagIndex);
while (theTagStr != nsnull) {
eHTMLTags theTag = nsHTMLTags::LookupTag(nsCAutoString(theTagStr));
if((eHTMLTag_userdefined!=theTag) && (theTag <= NS_HTML_TAG_MAX)){
theTopic=GetTopic(aTopic);
if(!theTopic)
theTopic=CreateTopic(aTopic);
if(theTopic) {
theTopic->RegisterObserverForTag(theElementObserver,theTag);
}
}
theTagIndex++;
theTagStr = theElementObserver->GetTagNameAt(theTagIndex);
}
}
void
nsObserverEntry::RemoveObserver(nsIElementObserver *aObserver)
{
for (PRInt32 i=0; i <= NS_HTML_TAG_MAX; i++){
if (mObservers[i]) {
nsISupports* obs = aObserver;
PRBool removed = mObservers[i]->RemoveElement(obs);
if (removed) {
NS_RELEASE(obs);
}
}
NS_IF_RELEASE(theEnum);
}
}
/**
* This method will maintain lists of observers registered for specific tags.
*
* @update rickg 03.23.2000
* @param aTopic - The topic under which observers register for.
* @return if SUCCESS return NS_OK else return ERROR code.
*/
void CObserverService::UnregisterObservers(const nsString& aTopic) {
}
/**
* This method will notify observers registered for specific tags.
*
* @update rickg 03.23.2000
* @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,
void* aUniqueID,
const nsString& aTopic,
nsIParser* aParser) {
nsresult result=NS_OK;
nsObserverTopic *theTopic=GetTopic(aTopic);
if(theTopic) {
result=theTopic->Notify(aTag,aNode,aUniqueID,aParser);
}
return result;
}
/**
* This method will look for the list of observers registered for
* a specific tag.
*
* @update rickg 03.23.2000
* @param aTag - The tag for which observers could be waiting for.
* @return if FOUND return "observer list" else return nsnull;
*
*/
nsDeque* CObserverService::GetObserversForTagInTopic(eHTMLTags aTag,const nsString& aTopic) {
nsObserverTopic *theTopic=GetTopic(aTopic);
if(theTopic) {
return theTopic->GetObserversForTag(aTag);
}
return 0;
}

View File

@@ -56,11 +56,10 @@
#include "nsIDTD.h"
#include "nsITokenizer.h"
#include "nsString.h"
#include "nsIElementObserver.h"
#include "nsIParserNode.h"
#include "nsFixedSizeAllocator.h"
#include "nsVoidArray.h"
#include "nsIObserverService.h"
#include "nsIParserService.h"
#define IF_HOLD(_ptr) \
PR_BEGIN_MACRO \
@@ -533,53 +532,23 @@ struct CRCStruct {
registering tags.
**************************************************************/
class nsObserverTopic {
class nsObserverEntry : public nsIObserverEntry {
public:
nsObserverTopic(const nsString& aTopic);
~nsObserverTopic();
PRBool Matches(const nsString& aTopic);
void RegisterObserverForTag(nsIElementObserver *anObserver,eHTMLTags aTag);
nsDeque* GetObserversForTag(eHTMLTags aTag);
nsresult Notify(eHTMLTags aTag,nsIParserNode& aNode,void* aUniqueID,nsIParser* aParser);
NS_DECL_ISUPPORTS
nsObserverEntry(const nsAString& aTopic);
virtual ~nsObserverEntry();
nsString mTopic;
nsString mCharsetKey;
nsString mSourceKey;
nsString mDTDKey;
nsDeque* mObservers[NS_HTML_TAG_MAX + 1];
};
NS_IMETHOD Notify(nsIParserNode* aNode,
nsIParser* aParser,
nsISupports* aWebShell);
/******************************************************************************
This class is used to store ref's to token observers during the parse phase.
Note that for simplicity, this is a singleton that is constructed in the
CNavDTD and shared for the duration of the application session. Later on it
might be nice to use a more dynamic approach that would permit observers to
come and go on a document basis.
******************************************************************************/
class CObserverService {
public:
CObserverService();
~CObserverService();
nsDeque* GetObserversForTagInTopic(eHTMLTags aTag,const nsString& aTopic);
nsresult Notify( eHTMLTags aTag,
nsIParserNode& aNode,
void* aUniqueID,
const nsString& aTopic,
nsIParser* aParser);
nsObserverTopic* GetTopic(const nsString& aTopic);
nsObserverTopic* CreateTopic(const nsString& aTopic);
// Do allocation and release of gObserverService
// These are called from the module init and shutdown
static nsresult InitGlobals();
static void ReleaseGlobals();
nsresult AddObserver(nsIElementObserver* aObserver,eHTMLTags aTag);
void RemoveObserver(nsIElementObserver* aObserver);
PRBool Matches(const nsAString& aTopic);
protected:
void RegisterObservers(const nsString& aTopic);
void UnregisterObservers(const nsString& aTopic);
nsDeque mTopics; //each topic holds a list of observers per tag.
static nsIObserverService *gObserverService;
nsString mTopic;
nsVoidArray* mObservers[NS_HTML_TAG_MAX + 1];
};
/*********************************************************************************************/

View File

@@ -72,6 +72,7 @@ public:
NS_IMETHOD AddDocTypeDecl(const nsIParserNode& aNode, PRInt32 aMode=0);
NS_IMETHOD FlushPendingNotifications() {return NS_OK; }
NS_IMETHOD SetDocumentCharset(nsAWritableString& aCharset) {return NS_OK;}
NS_IMETHOD NotifyTagObservers(nsIParserNode* aNode) { return NS_OK; }
// nsIHTMLContentSink
NS_IMETHOD SetTitle(const nsString& aValue);

View File

@@ -74,6 +74,7 @@ public:
NS_IMETHOD AddDocTypeDecl(const nsIParserNode& aNode, PRInt32 aMode=0);
NS_IMETHOD FlushPendingNotifications() { return NS_OK; }
NS_IMETHOD SetDocumentCharset(nsAWritableString& aCharset) { return NS_OK; }
NS_IMETHOD NotifyTagObservers(nsIParserNode* aNode) { return NS_OK; }
// nsIHTMLContentSink
NS_IMETHOD SetTitle(const nsString& aValue);

View File

@@ -356,7 +356,6 @@ nsParser::nsParser(nsITokenObserver* anObserver) {
mObserversEnabled=PR_TRUE;
mCommand=eViewNormal;
mParserEnabled=PR_TRUE;
mBundle=nsnull;
mPendingContinueEvent=PR_FALSE;
mCanInterrupt=PR_FALSE;
@@ -405,7 +404,6 @@ nsParser::~nsParser() {
NS_IF_RELEASE(mProgressEventSink);
NS_IF_RELEASE(mSink);
NS_IF_RELEASE(mParserFilter);
NS_IF_RELEASE(mBundle);
//don't forget to add code here to delete
//what may be several contexts...
@@ -456,9 +454,6 @@ nsresult nsParser::QueryInterface(const nsIID& aIID, void** aInstancePtr)
else if(aIID.Equals(kCParserCID)) { //do this class...
*aInstancePtr = (nsParser*)(this);
}
else if(aIID.Equals(NS_GET_IID(nsISupportsParserBundle))) {
*aInstancePtr = (nsISupportsParserBundle*)(this);
}
else {
*aInstancePtr=0;
return NS_NOINTERFACE;
@@ -1031,7 +1026,7 @@ static void VerifyPublicIDs()
NS_NOTREACHED("doctype not lower case");
printf("Doctype %s not lower case.\n", kPublicIDs[i].name);
}
}
}
}
}
#endif
@@ -1422,7 +1417,6 @@ nsresult nsParser::DidBuildModel(nsresult anErrorCode) {
result = mParserContext->mDTD->DidBuildModel(anErrorCode,PRBool(0==mParserContext->mPrevContext),this,mSink);
}
//Ref. to bug 61462.
NS_IF_RELEASE(mBundle);
}//if
}
@@ -2725,133 +2719,4 @@ nsParser::GetDTD(nsIDTD** aDTD)
}
return NS_OK;
}
/**
* Get the observer service
*
* @update rickg 11/22/99
* @return ptr to server or NULL
*/
CObserverService* nsParser::GetObserverService(void) {
//XXX Hack! this should be XPCOM based!
if(mObserversEnabled)
return &mObserverService;
return 0;
}
/**
* Store data into the bundle.
*
* @update harishd 05/10/00
* @param aData - The data to be stored.
* @return NS_OK if all went well else ERROR.
*/
NS_IMETHODIMP
nsParser::SetDataIntoBundle(const nsString& aKey,nsISupports* anObject) {
nsresult result=NS_OK;
if(!mBundle) {
mBundle = new nsParserBundle();
if(mBundle==nsnull) return NS_ERROR_OUT_OF_MEMORY;
NS_ADDREF(mBundle);
}
result=mBundle->SetDataIntoBundle(aKey,anObject);
return result;
}
/**
* Retrieve data from the bundle by IID.
* NOTE: The object retireved should not be released
*
* @update harishd 05/10/00
* @param aIID - The ID to identify the correct object in the bundle
* @return Return object if found in bundle else return NULL.
*/
NS_IMETHODIMP
nsParser::GetDataFromBundle(const nsString& aKey,nsISupports** anObject) {
nsresult result=NS_OK;
result=mBundle->GetDataFromBundle(aKey,anObject);
return result;
}
NS_IMPL_ISUPPORTS1(nsParserBundle,
nsISupportsParserBundle
);
/**
* Release data from the Hash table
*
* @update harishd 05/10/00
*/
static PRBool PR_CALLBACK ReleaseData(nsHashKey* aKey, void* aData, void* aClosure) {
nsISupports* object = (nsISupports*)aData;
NS_RELEASE(object);
return PR_TRUE;
}
/**
*
* @update harishd 05/10/00
*/
nsParserBundle::nsParserBundle (){
NS_INIT_REFCNT();
mData=new nsHashtable(5);
}
/**
* Release objects from the bundle.
*
* @update harishd 05/10/00
*/
nsParserBundle::~nsParserBundle () {
mData->Enumerate(ReleaseData);
delete mData;
}
/**
* Store data into the bundle.
*
* @update harishd 05/10/00
* @param aData - The data to be stored.
* @return NS_OK if all went well else ERROR.
*/
NS_IMETHODIMP
nsParserBundle::SetDataIntoBundle(const nsString& aKey,nsISupports* anObject) {
nsresult result=NS_OK;
if(anObject) {
nsStringKey key(aKey);
PRBool found=mData->Exists(&key);
if(!found) {
NS_ADDREF(anObject);
mData->Put(&key,anObject);
}
}
return result;
}
/**
* Retrieve data from the bundle by IID.
* NOTE: The object retrieved should not be released.
*
* @update harishd 05/10/00
* @param aIID - The ID to identify the correct object in the bundle
* @return Return object if found in bundle else return NULL.
*/
NS_IMETHODIMP
nsParserBundle::GetDataFromBundle(const nsString& aKey,nsISupports** anObject) {
nsresult result=NS_OK;
nsStringKey key(aKey);
*anObject=(mData)? (nsISupports*)mData->Get(&key):nsnull;
if(*anObject) {
NS_ADDREF(*anObject);
}
else{
result=NS_ERROR_NULL_POINTER;
}
return result;
}
}

View File

@@ -93,7 +93,6 @@ class nsIDTD;
class nsScanner;
class nsIParserFilter;
class nsIProgressEventSink;
class nsParserBundle;
#ifdef XP_WIN
#pragma warning( disable : 4275 )
@@ -101,7 +100,6 @@ class nsParserBundle;
class nsParser : public nsIParser,
public nsISupportsParserBundle,
public nsIStreamListener{
@@ -287,8 +285,6 @@ class nsParser : public nsIParser,
CParserContext* PopContext();
CParserContext* PeekContext() {return mParserContext;}
const nsParserBundle* GetParserBundle() { return mBundle; }
/**
*
* @update gess 1/22/99
@@ -320,20 +316,7 @@ class nsParser : public nsIParser,
* @return NS_OK if successful, NS_ERROR_FAILURE for runtime error
*/
NS_IMETHOD GetDTD(nsIDTD** aDTD);
/**
* Call this to access observer dictionary ( internal to parser )
* @update harishd 06/27/99
* @param
* @return
*/
CObserverService* GetObserverService(void);
// nsISupportsParserBundle
NS_IMETHOD GetDataFromBundle(const nsString& aKey,nsISupports** anObject);
NS_IMETHOD SetDataIntoBundle(const nsString& aKey,nsISupports* anObject);
/**
* Call this method to determine a DTD for a DOCTYPE
*
@@ -490,11 +473,9 @@ protected:
nsString mCharset;
nsCharsetSource mCharsetSource;
nsresult mInternalState;
CObserverService mObserverService;
PRBool mObserversEnabled;
nsString mCommandStr;
PRBool mParserEnabled;
nsParserBundle* mBundle;
nsTokenAllocator mTokenAllocator;
nsCOMPtr<nsIEventQueue> mEventQueue;
@@ -508,37 +489,5 @@ public:
MOZ_TIMER_DECLARE(mTokenizeTime)
};
// -----------------------------------------------------------------
class nsParserBundle : public nsISupportsParserBundle {
public:
NS_DECL_ISUPPORTS
nsParserBundle ();
virtual ~nsParserBundle ();
/**
* Retrieve data from the bundle by IID.
*
* @update harishd 05/10/00
* @param aIID - The ID to identify the correct object in the bundle
* @return Return object if found in bundle else return NULL.
*/
NS_IMETHOD GetDataFromBundle(const nsString& aKey,nsISupports** anObject);
/**
* Store data into the bundle.
*
* @update harishd 05/10/00
* @param aData - The data to be stored.
* @return NS_OK if all went well else ERROR.
*/
NS_IMETHOD SetDataIntoBundle(const nsString& aKey,nsISupports* anObject);
protected:
nsHashtable* mData;
};
#endif

View File

@@ -53,115 +53,13 @@
#include "nsHTMLTokenizer.h"
//#include "nsTextTokenizer.h"
#include "nsExpatTokenizer.h"
#include "nsIParserService.h"
#include "nsElementTable.h"
#include "nsParserService.h"
#ifdef NS_DEBUG
#include "nsLoggingSink.h"
#endif
class nsParserService : public nsIParserService {
public:
nsParserService();
virtual ~nsParserService();
NS_DECL_ISUPPORTS
NS_IMETHOD HTMLAtomTagToId(nsIAtom* aAtom, PRInt32* aId) const;
NS_IMETHOD HTMLStringTagToId(const nsString &aTag, PRInt32* aId) const;
NS_IMETHOD HTMLIdToStringTag(PRInt32 aId, nsString& aTag) const;
NS_IMETHOD HTMLConvertEntityToUnicode(const nsString& aEntity,
PRInt32* aUnicode) const;
NS_IMETHOD HTMLConvertUnicodeToEntity(PRInt32 aUnicode,
nsCString& aEntity) const;
NS_IMETHOD IsContainer(PRInt32 aId, PRBool& aIsContainer) const;
NS_IMETHOD IsBlock(PRInt32 aId, PRBool& aIsBlock) const;
};
nsParserService::nsParserService()
{
NS_INIT_ISUPPORTS();
}
nsParserService::~nsParserService()
{
}
NS_IMPL_ISUPPORTS1(nsParserService, nsIParserService)
NS_IMETHODIMP
nsParserService::HTMLAtomTagToId(nsIAtom* aAtom, PRInt32* aId) const
{
NS_ENSURE_ARG_POINTER(aAtom);
nsAutoString tagName;
aAtom->ToString(tagName);
*aId = nsHTMLTags::LookupTag(tagName);
return NS_OK;
}
NS_IMETHODIMP
nsParserService::HTMLStringTagToId(const nsString &aTag, PRInt32* aId) const
{
*aId = nsHTMLTags::LookupTag(aTag);
return NS_OK;
}
NS_IMETHODIMP
nsParserService::HTMLIdToStringTag(PRInt32 aId, nsString& aTag) const
{
aTag.AssignWithConversion( nsHTMLTags::GetStringValue((nsHTMLTag)aId) );
return NS_OK;
}
NS_IMETHODIMP
nsParserService::HTMLConvertEntityToUnicode(const nsString& aEntity,
PRInt32* aUnicode) const
{
*aUnicode = nsHTMLEntities::EntityToUnicode(aEntity);
return NS_OK;
}
NS_IMETHODIMP
nsParserService::HTMLConvertUnicodeToEntity(PRInt32 aUnicode,
nsCString& aEntity) const
{
const char* str = nsHTMLEntities::UnicodeToEntity(aUnicode);
if (str) {
aEntity.Assign(str);
}
return NS_OK;
}
NS_IMETHODIMP
nsParserService::IsContainer(PRInt32 aId, PRBool& aIsContainer) const
{
aIsContainer = nsHTMLElement::IsContainer((eHTMLTags)aId);
return NS_OK;
}
NS_IMETHODIMP
nsParserService::IsBlock(PRInt32 aId, PRBool& aIsBlock) const
{
if((aId>eHTMLTag_unknown) && (aId<eHTMLTag_userdefined)) {
aIsBlock=((gHTMLElements[aId].IsMemberOf(kBlock)) ||
(gHTMLElements[aId].IsMemberOf(kBlockEntity)) ||
(gHTMLElements[aId].IsMemberOf(kHeading)) ||
(gHTMLElements[aId].IsMemberOf(kPreformatted))||
(gHTMLElements[aId].IsMemberOf(kList)));
}
else {
aIsBlock = PR_FALSE;
}
return NS_OK;
}
//----------------------------------------------------------------------
#ifdef NS_DEBUG
@@ -203,7 +101,6 @@ Initialize(nsIModule* aSelf)
nsHTMLEntities::AddRefTable();
InitializeElementTable();
CNewlineToken::AllocNewline();
CObserverService::InitGlobals();
gInitialized = PR_TRUE;
}
return NS_OK;
@@ -219,7 +116,6 @@ Shutdown(nsIModule* aSelf)
nsParser::FreeSharedObjects();
DeleteElementTable();
CNewlineToken::FreeNewline();
CObserverService::ReleaseGlobals();
gInitialized = PR_FALSE;
}
}

View File

@@ -80,17 +80,16 @@
#include "prtypes.h" //this is here for debug reasons...
#include "prio.h"
#include "plstr.h"
#include "prmem.h"
#ifdef RAPTOR_PERF_METRICS
#include "stopwatch.h"
Stopwatch vsTimer;
#endif
static NS_DEFINE_IID(kClassIID, NS_VIEWSOURCE_HTML_IID);
static NS_DEFINE_IID(kClassIID, NS_VIEWSOURCE_HTML_IID);
static int gErrorThreshold = 10;
// Define this to dump the viewsource stuff to a file
@@ -1099,12 +1098,7 @@ NS_IMETHODIMP CViewSourceHTML::HandleToken(CToken* aToken,nsIParser* aParser) {
else result=WriteTag(mStartTag,startValue,aToken->GetAttributeCount(),PR_TRUE);
if((ePlainText!=mDocType) && mParser && (NS_OK==result)) {
CObserverService* theService=mParser->GetObserverService();
if(theService) {
eHTMLTags theTag=(eHTMLTags)theToken->GetTypeID();
const nsISupportsParserBundle* bundle=mParser->GetParserBundle();
result=theService->Notify(theTag,theContext.mTokenNode,(void*)bundle, mMimeType, mParser);
}
result = mSink->NotifyTagObservers(&theContext.mTokenNode);
}
}
break;