Fix line numbers in html. b=111576, r=heikki, sr=jst, a=asa,chofmann

This commit is contained in:
harishd%netscape.com 2002-04-10 22:16:46 +00:00
Родитель 772ad9c920
Коммит 7609e93846
58 изменённых файлов: 1468 добавлений и 1306 удалений

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

@ -855,14 +855,20 @@ HTMLContentSink::CreateContentObject(const nsIParserNode& aNode,
if (NS_SUCCEEDED(rv)) {
// XXX if the parser treated the text in a textarea like a normal textnode
// we wouldn't need to do this.
const nsAString* skippedContent = nsnull;
nsAutoString skippedContent;
if (aNodeType == eHTMLTag_textarea) {
skippedContent = &aNode.GetSkippedContent();
nsCOMPtr<nsIDTD> dtd;
mParser->GetDTD(getter_AddRefs(dtd));
NS_ENSURE_TRUE(dtd, NS_ERROR_FAILURE);
PRInt32 lineNo = 0;
dtd->CollectSkippedContent(eHTMLTag_textarea, skippedContent, lineNo);
}
// Make the content object
rv = MakeContentObject(aNodeType, nodeInfo, aForm, aWebShell,
aResult, skippedContent, !!mInsideNoXXXTag,
PR_TRUE);
rv = MakeContentObject(aNodeType, nodeInfo, aForm,
aWebShell, aResult, &skippedContent,
!!mInsideNoXXXTag, PR_TRUE);
PRInt32 id;
mDocument->GetAndIncrementContentID(&id);
@ -5099,15 +5105,22 @@ HTMLContentSink::ProcessSCRIPTTag(const nsIParserNode& aNode)
return rv;
}
nsCOMPtr<nsIDTD> dtd;
mParser->GetDTD(getter_AddRefs(dtd));
NS_ENSURE_TRUE(dtd, NS_ERROR_FAILURE);
nsAutoString script;
PRInt32 lineNo = 0;
dtd->CollectSkippedContent(eHTMLTag_script, script, lineNo);
nsCOMPtr<nsIScriptElement> sele(do_QueryInterface(element));
if (sele) {
sele->SetLineNumber((PRUint32)aNode.GetSourceLineNumber());
sele->SetLineNumber((PRUint32)lineNo);
}
// Create a text node holding the content
// First, get the text content of the script tag
nsAutoString script;
script.Assign(aNode.GetSkippedContent());
if (!script.IsEmpty()) {
nsCOMPtr<nsIContent> text;
@ -5226,7 +5239,14 @@ HTMLContentSink::ProcessSTYLETag(const nsIParserNode& aNode)
}
// The skipped content contains the inline style data
const nsString& content = aNode.GetSkippedContent();
nsCOMPtr<nsIDTD> dtd;
mParser->GetDTD(getter_AddRefs(dtd));
NS_ENSURE_TRUE(dtd, NS_ERROR_FAILURE);
nsAutoString content;
PRInt32 lineNo = 0;
dtd->CollectSkippedContent(eHTMLTag_style, content, lineNo);
if (!content.IsEmpty()) {
// Create a text node holding the content

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

@ -629,7 +629,15 @@ nsHTMLFragmentContentSink::AddLeaf(const nsIParserNode& aNode)
nodeType == eHTMLTag_xmp) {
// Create a text node holding the content
result=AddTextToContent(content,aNode.GetSkippedContent());
nsCOMPtr<nsIDTD> dtd;
mParser->GetDTD(getter_AddRefs(dtd));
NS_ENSURE_TRUE(dtd, NS_ERROR_FAILURE);
nsAutoString skippedContent;
PRInt32 lineNo = 0;
dtd->CollectSkippedContent(nodeType, skippedContent, lineNo);
result=AddTextToContent(content, skippedContent);
}
else if (nodeType == eHTMLTag_img || nodeType == eHTMLTag_frame
|| nodeType == eHTMLTag_input) // elements with 'SRC='

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

@ -126,14 +126,14 @@ class CStartToken: public CHTMLToken {
virtual const char* GetClassName(void);
virtual PRInt32 GetTokenType(void);
PRBool IsEmpty(void);
void SetEmpty(PRBool aValue);
virtual PRBool IsEmpty(void);
virtual void SetEmpty(PRBool aValue);
#ifdef DEBUG
virtual void DebugDumpSource(nsOutputStream& out);
#endif
virtual const nsAString& GetStringValue();
virtual void GetSource(nsString& anOutputString);
virtual void AppendSource(nsString& anOutputString);
virtual void AppendSourceTo(nsAString& anOutputString);
//the following info is used to set well-formedness state on start tags...
virtual eContainerInfo GetContainerInfo(void) const {return mContainerInfo;}
@ -185,7 +185,7 @@ class CEndToken: public CHTMLToken {
#endif
virtual const nsAString& GetStringValue();
virtual void GetSource(nsString& anOutputString);
virtual void AppendSource(nsString& anOutputString);
virtual void AppendSourceTo(nsAString& anOutputString);
protected:
nsString mTextValue;
@ -241,7 +241,7 @@ class CEntityToken : public CHTMLToken {
#endif
virtual const nsAString& GetStringValue(void);
virtual void GetSource(nsString& anOutputString);
virtual void AppendSource(nsString& anOutputString);
virtual void AppendSourceTo(nsAString& anOutputString);
protected:
nsString mTextValue;
@ -373,7 +373,7 @@ class CAttributeToken: public CHTMLToken {
#endif
virtual const nsAString& GetStringValue(void);
virtual void GetSource(nsString& anOutputString);
virtual void AppendSource(nsString& anOutputString);
virtual void AppendSourceTo(nsAString& anOutputString);
#ifdef DEBUG
virtual void DebugDumpSource(nsOutputStream& out);
#endif

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

@ -115,7 +115,8 @@ public:
PRInt32 aVersion) = 0;
NS_IMETHOD WillBuildModel(const CParserContext& aParserContext,
nsIContentSink* aSink=0) = 0;
nsITokenizer* aTokenizer,
nsIContentSink* aSink) = 0;
/**
* Called by the parser after the parsing process has concluded
@ -125,7 +126,7 @@ public:
*/
NS_IMETHOD DidBuildModel(nsresult anErrorCode, PRBool aNotifySink,
nsIParser* aParser,
nsIContentSink* aSink = nsnull) = 0;
nsIContentSink* aSink) = 0;
/**
* Called by the parser after the parsing process has concluded
@ -134,8 +135,8 @@ public:
* @return
*/
NS_IMETHOD BuildModel(nsIParser* aParser, nsITokenizer* aTokenizer,
nsITokenObserver* anObserver = nsnull,
nsIContentSink* aSink = nsnull) = 0;
nsITokenObserver* anObserver,
nsIContentSink* aSink) = 0;
/**
* Called during model building phase of parse process. Each token
@ -149,14 +150,6 @@ public:
*/
NS_IMETHOD HandleToken(CToken* aToken,nsIParser* aParser) = 0;
/**
*
* @update gess 12/20/99
* @param ptr-ref to (out) tokenizer
* @return nsresult
*/
NS_IMETHOD GetTokenizer(nsITokenizer*& aTokenizer) = 0;
/**
* If the parse process gets interrupted midway, this method is
* called by the parser prior to resuming the process.
@ -206,6 +199,10 @@ public:
*/
NS_IMETHOD_(void) Terminate() = 0;
NS_IMETHOD_(PRInt32) GetType() = 0;
NS_IMETHOD CollectSkippedContent(PRInt32 aTag, nsAString& aContent, PRInt32 &aLineNo) = 0;
/* XXX Temporary measure, pending further work by RickG */
@ -235,16 +232,17 @@ public:
NS_IMETHOD_(const nsIID&) GetMostDerivedIID(void) const;\
NS_IMETHOD CreateNewInstance(nsIDTD** aInstancePtrResult);\
NS_IMETHOD_(eAutoDetectResult) CanParse(CParserContext& aParserContext, const nsString& aBuffer, PRInt32 aVersion);\
NS_IMETHOD WillBuildModel( const CParserContext& aParserContext,nsIContentSink* aSink=0);\
NS_IMETHOD DidBuildModel(nsresult anErrorCode,PRBool aNotifySink,nsIParser* aParser,nsIContentSink* aSink=0);\
NS_IMETHOD BuildModel(nsIParser* aParser,nsITokenizer* aTokenizer,nsITokenObserver* anObserver=0,nsIContentSink* aSink=0);\
NS_IMETHOD WillBuildModel( const CParserContext& aParserContext, nsITokenizer* aTokenizer, nsIContentSink* aSink);\
NS_IMETHOD DidBuildModel(nsresult anErrorCode,PRBool aNotifySink,nsIParser* aParser,nsIContentSink* aSink);\
NS_IMETHOD BuildModel(nsIParser* aParser,nsITokenizer* aTokenizer,nsITokenObserver* anObserver,nsIContentSink* aSink);\
NS_IMETHOD HandleToken(CToken* aToken,nsIParser* aParser);\
NS_IMETHOD GetTokenizer(nsITokenizer*& aTokenizer);\
NS_IMETHOD WillResumeParse(nsIContentSink* aSink = 0);\
NS_IMETHOD WillInterruptParse(nsIContentSink* aSink = 0);\
NS_IMETHOD_(PRBool) CanContain(PRInt32 aParent,PRInt32 aChild) const;\
NS_IMETHOD_(PRBool) IsContainer(PRInt32 aTag) const;\
NS_IMETHOD CollectSkippedContent(PRInt32 aTag, nsAString& aContent, PRInt32 &aLineNo);\
NS_IMETHOD_(void) Terminate();\
NS_IMETHOD_(PRInt32) GetType(); \
NS_IMETHOD StringTagToIntTag(const nsAString &aTag, PRInt32* aIntTag) const ;\
NS_IMETHOD_(const PRUnichar *) IntTagToStringTag(PRInt32 aIntTag) const ;\
NS_IMETHOD ConvertEntityToUnicode(const nsAString& aEntity, PRInt32* aUnicode) const ;\

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

@ -99,13 +99,6 @@ class nsIParserNode { // XXX Should be nsAParserNode
*/
virtual const nsAString& GetText() const =0; //get plain text if available
/**
* Retrieve skipped context from node
* @update gess5/11/98
* @return string containing skipped content
*/
virtual const nsString& GetSkippedContent() const =0;
/**
* Retrieve the type of the parser node.
* @update gess5/11/98

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

@ -188,7 +188,7 @@ class CToken {
/** @update harishd 03/23/00
* @return reference to string containing string value
*/
virtual void AppendSource(nsString& anOutputString);
virtual void AppendSourceTo(nsAString& anOutputString);
/**
* Sets the ordinal value of this token (not currently used)
@ -204,13 +204,6 @@ class CToken {
*/
virtual PRInt32 GetTypeID(void);
/**
* Sets the # of attributes found for this token.
* @update gess5/11/98
* @param value is the attr count
*/
virtual void SetAttributeCount(PRInt16 aValue);
/**
* Getter which retrieves the current attribute count for this token
* @update gess5/11/98
@ -269,6 +262,34 @@ class CToken {
*/
virtual PRBool IsWellFormed(void) const {return PR_FALSE;}
virtual PRBool IsEmpty(void) { return PR_FALSE; }
/**
* If aValue is TRUE then the token represents a short-hand tag
*/
virtual void SetEmpty(PRBool aValue) { return ; }
PRInt32 GetNewlineCount()
{
return mNewlineCount;
}
void SetNewlineCount(PRInt32 aCount)
{
mNewlineCount = aCount;
}
PRInt32 GetLineNumber()
{
return mLineNumber;
}
void SetLineNumber(PRInt32 aLineNumber)
{
mLineNumber = mLineNumber == 0 ? aLineNumber : mLineNumber;
}
void SetAttributeCount(PRInt16 aValue) { mAttrCount = aValue; }
/**
* perform self test.
@ -278,7 +299,7 @@ class CToken {
static int GetTokenCount();
PRInt32 mNewlineCount;
protected:
/**
@ -288,6 +309,8 @@ protected:
PRInt32 mTypeID;
PRInt32 mUseCount;
PRInt32 mNewlineCount;
PRInt32 mLineNumber;
PRInt16 mAttrCount;
};

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

@ -266,8 +266,6 @@ CNavDTD::~CNavDTD(){
mBodyContext=0;
}
NS_IF_RELEASE(mTokenizer);
if(mTempContext) {
delete mTempContext;
mTempContext=0;
@ -385,7 +383,9 @@ CNavDTD::CanParse(CParserContext& aParserContext,
* @param aSink
* @return error code (almost always 0)
*/
nsresult CNavDTD::WillBuildModel( const CParserContext& aParserContext,nsIContentSink* aSink) {
nsresult CNavDTD::WillBuildModel(const CParserContext& aParserContext,
nsITokenizer* aTokenizer,
nsIContentSink* aSink) {
nsresult result=NS_OK;
mFilename=aParserContext.mScanner->GetFilename();
@ -394,7 +394,7 @@ nsresult CNavDTD::WillBuildModel( const CParserContext& aParserContext,nsIConte
mDTDMode=aParserContext.mDTDMode;
mParserCommand=aParserContext.mParserCommand;
mMimeType=aParserContext.mMimeType;
mTokenizer = aTokenizer;
mBodyContext->SetNodeAllocator(&mNodeAllocator);
if((!aParserContext.mPrevContext) && (aSink)) {
@ -471,97 +471,73 @@ nsresult CNavDTD::WillBuildModel( const CParserContext& aParserContext,nsIConte
nsresult CNavDTD::BuildModel(nsIParser* aParser,nsITokenizer* aTokenizer,nsITokenObserver* anObserver,nsIContentSink* aSink) {
NS_PRECONDITION(mBodyContext!=nsnull,"Create a context before calling build model");
nsresult result=NS_OK;
nsresult result = NS_OK;
if(aTokenizer) {
nsITokenizer* oldTokenizer=mTokenizer;
mTokenizer=aTokenizer;
mParser=(nsParser*)aParser;
if (aTokenizer && mSink && aParser) {
nsITokenizer* oldTokenizer = mTokenizer;
if(mTokenizer) {
mTokenAllocator=mTokenizer->GetTokenAllocator();
mTokenizer = aTokenizer;
mParser = (nsParser*)aParser;
mTokenAllocator = mTokenizer->GetTokenAllocator();
if(NS_FAILED(result)) return result;
if(mSink) {
if(!mBodyContext->GetCount()) {
CStartToken* theToken=nsnull;
if(ePlainText==mDocType) {
//we do this little trick for text files, in both normal and viewsource mode...
theToken=NS_STATIC_CAST(CStartToken*,mTokenAllocator->CreateTokenOfType(eToken_start,eHTMLTag_pre));
if(theToken) {
mTokenizer->PushTokenFront(theToken);
}
}
// always open a body if frames are disabled....
if(!(mFlags & NS_DTD_FLAG_FRAMES_ENABLED)) {
theToken=NS_STATIC_CAST(CStartToken*,mTokenAllocator->CreateTokenOfType(eToken_start,eHTMLTag_body,NS_LITERAL_STRING("body")));
mTokenizer->PushTokenFront(theToken);
}
//if the content model is empty, then begin by opening <html>...
theToken=NS_STATIC_CAST(CStartToken*,mTokenAllocator->CreateTokenOfType(eToken_start,eHTMLTag_html,NS_LITERAL_STRING("html")));
if(theToken) {
mTokenizer->PushTokenFront(theToken); //this token should get pushed on the context stack.
}
if (mBodyContext->GetCount() == 0) {
CStartToken* theToken=nsnull;
if(ePlainText==mDocType) {
//we do this little trick for text files, in both normal and viewsource mode...
theToken=NS_STATIC_CAST(CStartToken*,mTokenAllocator->CreateTokenOfType(eToken_start,eHTMLTag_pre));
if(theToken) {
mTokenizer->PushTokenFront(theToken);
}
mSink->WillProcessTokens();
while(NS_SUCCEEDED(result)){
//Currently nsIHTMLContentSink does nothing with a call to WillProcessAToken.
//mSink->WillProcessAToken();
#if 0
int n=aTokenizer->GetCount();
if(n>50) n=50;
for(int i=0;i<n;i++){
CToken* theToken=aTokenizer->GetTokenAt(i);
printf("\nToken[%i],%p",i,theToken);
}
printf("\n");
#endif
if(!(mFlags & NS_DTD_FLAG_STOP_PARSING)) {
CToken* theToken=mTokenizer->PopToken();
if(theToken) {
result=HandleToken(theToken,aParser);
}
else break;
}
else {
result = NS_ERROR_HTMLPARSER_STOPPARSING;
break;
}
if ((NS_ERROR_HTMLPARSER_INTERRUPTED == mSink->DidProcessAToken())) {
// The content sink has requested that DTD interrupt processing tokens
// So we need to make sure the parser is in a state where it can be
// interrupted.
// The mParser->CanInterrupt will return TRUE if BuildModel was called
// from a place in the parser where it prepared to handle a return value of
// NS_ERROR_HTMLPARSER_INTERRUPTED.
// If the parser has mPrevContext then it may be processing
// Script so we should not allow it to be interrupted.
if ((mParser->CanInterrupt()) &&
(nsnull == mParser->PeekContext()->mPrevContext) &&
(eHTMLTag_unknown==mSkipTarget)) {
result = NS_ERROR_HTMLPARSER_INTERRUPTED;
break;
}
}
}//while
mTokenizer=oldTokenizer;
//Currently nsIHTMLContentSink does nothing with a call to DidProcessATokens().
//mSink->DidProcessTokens();
}
// always open a body if frames are disabled....
if(!(mFlags & NS_DTD_FLAG_FRAMES_ENABLED)) {
theToken=NS_STATIC_CAST(CStartToken*,mTokenAllocator->CreateTokenOfType(eToken_start,eHTMLTag_body,NS_LITERAL_STRING("body")));
mTokenizer->PushTokenFront(theToken);
}
//if the content model is empty, then begin by opening <html>...
theToken=NS_STATIC_CAST(CStartToken*,mTokenAllocator->CreateTokenOfType(eToken_start,eHTMLTag_html,NS_LITERAL_STRING("html")));
if(theToken) {
mTokenizer->PushTokenFront(theToken); //this token should get pushed on the context stack.
}
}
mSink->WillProcessTokens();
while (NS_SUCCEEDED(result)) {
if (!(mFlags & NS_DTD_FLAG_STOP_PARSING)) {
CToken* theToken = mTokenizer->PopToken();
if (theToken) {
result = HandleToken(theToken,aParser);
}
else break;
}
else {
result = NS_ERROR_HTMLPARSER_STOPPARSING;
break;
}
if ((NS_ERROR_HTMLPARSER_INTERRUPTED == mSink->DidProcessAToken())) {
// The content sink has requested that DTD interrupt processing tokens
// So we need to make sure the parser is in a state where it can be
// interrupted.
// The mParser->CanInterrupt will return TRUE if BuildModel was called
// from a place in the parser where it prepared to handle a return value of
// NS_ERROR_HTMLPARSER_INTERRUPTED.
// If the parser has mPrevContext then it may be processing
// Script so we should not allow it to be interrupted.
if ((mParser->CanInterrupt()) &&
(nsnull == mParser->PeekContext()->mPrevContext) &&
(eHTMLTag_unknown==mSkipTarget)) {
result = NS_ERROR_HTMLPARSER_INTERRUPTED;
break;
}
}
}//while
mTokenizer = oldTokenizer;
}
else result=NS_ERROR_HTMLPARSER_BADTOKENIZER;
return result;
}
@ -688,6 +664,13 @@ CNavDTD::Terminate()
mFlags |= NS_DTD_FLAG_STOP_PARSING;
}
NS_IMETHODIMP_(PRInt32)
CNavDTD::GetType()
{
return NS_IPARSER_FLAG_HTML;
}
/**
* --- Backwards compatibility ---
* Use this method to determine if the tag in question needs a BODY.
@ -746,6 +729,10 @@ nsresult CNavDTD::HandleToken(CToken* aToken,nsIParser* aParser){
eHTMLTags theTag=(eHTMLTags)theToken->GetTypeID();
PRBool execSkipContent=PR_FALSE;
aToken->SetLineNumber(mLineNumber);
mLineNumber += aToken->GetNewlineCount();
/* ---------------------------------------------------------------------------------
To understand this little piece of code, you need to look below too.
In essence, this code caches "skipped content" until we find a given skiptarget.
@ -774,7 +761,7 @@ nsresult CNavDTD::HandleToken(CToken* aToken,nsIParser* aParser){
if(theTag != mBodyContext->Last() || theType!=eToken_end) {
// attribute source is a part of start token.
if(theType!=eToken_attribute) {
aToken->AppendSource(mScratch);
aToken->AppendSourceTo(mScratch);
}
IF_FREE(aToken, mTokenAllocator);
return result;
@ -818,7 +805,7 @@ nsresult CNavDTD::HandleToken(CToken* aToken,nsIParser* aParser){
// Fall through if the skipped content collection is |not| in progress - bug 124788
}
else {
mMisplacedContent.Push(theToken);
PushIntoMisplacedStack(theToken);
return result;
}
}
@ -867,7 +854,7 @@ nsresult CNavDTD::HandleToken(CToken* aToken,nsIParser* aParser){
//If you're here then we found a child of the body that was out of place.
//We're going to move it to the body by storing it temporarily on the misplaced stack.
//However, in quirks mode, a few tags request, ambiguosly, for a BODY. - Bugs 18928, 24204.-
mMisplacedContent.Push(aToken);
PushIntoMisplacedStack(aToken);
if(DoesRequireBody(aToken,mTokenizer)) {
CToken* theBodyToken=NS_STATIC_CAST(CToken*,mTokenAllocator->CreateTokenOfType(eToken_start,eHTMLTag_body,NS_LITERAL_STRING("body")));
result=HandleToken(theBodyToken,aParser);
@ -889,6 +876,8 @@ nsresult CNavDTD::HandleToken(CToken* aToken,nsIParser* aParser){
(gHTMLElements[theTag].mSkipTarget) &&
(!theStartToken->IsEmpty())) { // added empty token check for bug 44186
//create a new target
NS_ASSERTION(mSkippedContent.GetSize() == 0, "all the skipped content tokens did not get handled");
mSkippedContent.Empty();
mSkipTarget=gHTMLElements[theTag].mSkipTarget;
mSkippedContent.Push(theToken);
}
@ -969,7 +958,7 @@ nsresult CNavDTD::DidHandleStartTag(nsIParserNode& aNode,eHTMLTags aChildTag){
if(theNextToken) {
eHTMLTokenTypes theType=eHTMLTokenTypes(theNextToken->GetTokenType());
if(eToken_newline==theType){
mLineNumber++;
mLineNumber += theNextToken->GetNewlineCount();
theNextToken=mTokenizer->PopToken(); //skip 1st newline inside PRE and LISTING
IF_FREE(theNextToken, mTokenAllocator); // fix for Bug 29379
}//if
@ -983,10 +972,15 @@ nsresult CNavDTD::DidHandleStartTag(nsIParserNode& aNode,eHTMLTags aChildTag){
{
STOP_TIMER()
MOZ_TIMER_DEBUGLOG(("Stop: Parse Time: CNavDTD::DidHandleStartTag(), this=%p\n", this));
const nsString& theString=aNode.GetSkippedContent();
nsAutoString theString;
PRInt32 lineNo = 0;
result = CollectSkippedContent(aChildTag, theString, lineNo);
NS_ENSURE_SUCCESS(result, result);
if(0<theString.Length()) {
CTextToken *theToken=NS_STATIC_CAST(CTextToken*,mTokenAllocator->CreateTokenOfType(eToken_text,eHTMLTag_text,theString));
nsCParserNode theNode(theToken,0,mTokenAllocator);
nsCParserNode theNode(theToken, mTokenAllocator);
result=mSink->AddLeaf(theNode); //when the node get's destructed, so does the new token
}
MOZ_TIMER_DEBUGLOG(("Start: Parse Time: CNavDTD::DidHandleStartTag(), this=%p\n", this));
@ -1006,7 +1000,7 @@ nsresult CNavDTD::DidHandleStartTag(nsIParserNode& aNode,eHTMLTags aChildTag){
CTextToken theToken(theNumber);
PRInt32 theLineNumber=0;
nsCParserNode theNode(&theToken,theLineNumber,0 /*stack token*/);
nsCParserNode theNode(&theToken, 0 /*stack token*/);
result=mSink->AddLeaf(theNode);
}
break;
@ -1353,12 +1347,7 @@ void WriteTokenToLog(CToken* aToken) {
*/
nsresult CNavDTD::WillHandleStartTag(CToken* aToken,eHTMLTags aTag,nsIParserNode& aNode) {
nsresult result=NS_OK;
PRInt32 theAttrCount = aNode.GetAttributeCount();
//first let's see if there's some skipped content to deal with...
if(gHTMLElements[aTag].mSkipTarget) {
result=CollectSkippedContent(aNode,theAttrCount);
}
PRInt32 theAttrCount = aNode.GetAttributeCount();
//this little gem creates a special attribute for the editor team to use.
//The attribute only get's applied to unknown tags, and is used by ender
@ -1452,7 +1441,7 @@ nsresult CNavDTD::WillHandleStartTag(CToken* aToken,eHTMLTags aTag,nsIParserNode
//because this code calls CloseHead() directly, stack-based token/nodes are ok.
CEndToken theToken(eHTMLTag_head);
nsCParserNode theNode(&theToken,mLineNumber,0 /*stack token*/);
nsCParserNode theNode(&theToken, 0 /*stack token*/);
result=CloseHead(&theNode);
}
}
@ -1470,6 +1459,7 @@ static void PushMisplacedAttributes(nsIParserNode& aNode,nsDeque& aDeque,PRInt32
while(aCount){
theAttrToken=theAttrNode->PopAttributeToken();
if(theAttrToken) {
theAttrToken->SetNewlineCount(0);
aDeque.Push(theAttrToken);
}
aCount--;
@ -1518,7 +1508,7 @@ nsresult CNavDTD::HandleOmittedTag(CToken* aToken,eHTMLTags aChildTag,eHTMLTags
if(mBodyContext->mContextTopIndex>-1) {
mMisplacedContent.Push(aToken);
PushIntoMisplacedStack(aToken);
IF_HOLD(aToken); // Hold on to this token for later use.
@ -1526,8 +1516,14 @@ nsresult CNavDTD::HandleOmittedTag(CToken* aToken,eHTMLTags aChildTag,eHTMLTags
if(attrCount > 0) PushMisplacedAttributes(*aNode,mMisplacedContent,attrCount);
if(gHTMLElements[aChildTag].mSkipTarget) {
mMisplacedContent.Push(mTokenAllocator->CreateTokenOfType(eToken_text,eHTMLTag_text,aNode->GetSkippedContent()));
mMisplacedContent.Push(mTokenAllocator->CreateTokenOfType(eToken_end,aChildTag));
nsAutoString theString;
PRInt32 lineNo = 0;
result = CollectSkippedContent(aChildTag, theString, lineNo);
NS_ENSURE_SUCCESS(result, result);
PushIntoMisplacedStack(mTokenAllocator->CreateTokenOfType(eToken_text,eHTMLTag_text,theString));
PushIntoMisplacedStack(mTokenAllocator->CreateTokenOfType(eToken_end,aChildTag));
}
mFlags |= NS_DTD_FLAG_MISPLACED_CONTENT; // This state would help us in gathering all the misplaced elements
@ -1538,7 +1534,7 @@ nsresult CNavDTD::HandleOmittedTag(CToken* aToken,eHTMLTags aChildTag,eHTMLTags
IF_HOLD(aToken); // Hold on to this token for later use. Ref Bug. 53695
mMisplacedContent.Push(aToken);
PushIntoMisplacedStack(aToken);
// If the token is attributed then save those attributes too.
if(attrCount > 0) PushMisplacedAttributes(*aNode,mMisplacedContent,attrCount);
}
@ -1640,7 +1636,7 @@ nsresult CNavDTD::HandleStartToken(CToken* aToken) {
//Begin by gathering up attributes...
nsCParserNode* theNode=mNodeAllocator.CreateNode(aToken,mLineNumber,mTokenAllocator);
nsCParserNode* theNode=mNodeAllocator.CreateNode(aToken, mTokenAllocator);
eHTMLTags theChildTag=(eHTMLTags)aToken->GetTypeID();
PRInt16 attrCount=aToken->GetAttributeCount();
@ -1679,15 +1675,10 @@ nsresult CNavDTD::HandleStartToken(CToken* aToken) {
}
}
mLineNumber += aToken->mNewlineCount;
PRBool theExclusive=PR_FALSE;
theHeadIsParent=nsHTMLElement::IsChildOfHead(theChildTag,theExclusive);
switch(theChildTag) {
case eHTMLTag_newline:
mLineNumber++;
break;
case eHTMLTag_area:
if(!mOpenMapCount) isTokenHandled=PR_TRUE;
@ -1931,7 +1922,7 @@ nsresult CNavDTD::HandleEndToken(CToken* aToken) {
case eHTMLTag_form:
{
//this is safe because we call close container directly. This node/token is not cached.
nsCParserNode theNode((CHTMLToken*)aToken,mLineNumber,mTokenAllocator);
nsCParserNode theNode((CHTMLToken*)aToken, mTokenAllocator);
result=CloseContainer(&theNode,theChildTag,PR_FALSE);
}
break;
@ -2163,7 +2154,7 @@ nsresult CNavDTD::HandleEntityToken(CToken* aToken) {
eHTMLTags theParentTag=mBodyContext->Last();
nsCParserNode* theNode=mNodeAllocator.CreateNode(aToken,mLineNumber,mTokenAllocator);
nsCParserNode* theNode=mNodeAllocator.CreateNode(aToken, mTokenAllocator);
if(theNode) {
PRBool theParentContains=-1; //set to -1 to force CanOmit to recompute...
if(CanOmit(theParentTag,eHTMLTag_entity,theParentContains)) {
@ -2196,11 +2187,8 @@ nsresult CNavDTD::HandleCommentToken(CToken* aToken) {
nsresult result=NS_OK;
CCommentToken* theToken = NS_STATIC_CAST(CCommentToken*,aToken);
const nsAString& theComment = theToken->GetStringValue();
mLineNumber += CountCharInReadable(theComment, PRUnichar(kNewLine));
nsCParserNode* theNode=mNodeAllocator.CreateNode(aToken, mTokenAllocator);
nsCParserNode* theNode=mNodeAllocator.CreateNode(aToken,mLineNumber,mTokenAllocator);
if(theNode) {
#ifdef RICKG_DEBUG
@ -2234,7 +2222,7 @@ nsresult CNavDTD::HandleCommentToken(CToken* aToken) {
*/
nsresult CNavDTD::HandleAttributeToken(CToken* aToken) {
NS_PRECONDITION(0!=aToken,kNullToken);
NS_ERROR("attribute encountered -- this shouldn't happen!");
NS_ERROR("attribute encountered -- this shouldn't happen unless the attribute was not part of a start tag!");
return NS_OK;
}
@ -2277,7 +2265,7 @@ nsresult CNavDTD::HandleProcessingInstructionToken(CToken* aToken){
nsresult result=NS_OK;
nsCParserNode* theNode=mNodeAllocator.CreateNode(aToken,mLineNumber,mTokenAllocator);
nsCParserNode* theNode=mNodeAllocator.CreateNode(aToken, mTokenAllocator);
if(theNode) {
#ifdef RICKG_DEBUG
@ -2327,7 +2315,7 @@ nsresult CNavDTD::HandleDocTypeDeclToken(CToken* aToken){
docTypeStr.Cut(0,2); // Now remove "<!" from the begining
theToken->SetStringValue(docTypeStr);
nsCParserNode* theNode=mNodeAllocator.CreateNode(aToken,mLineNumber,mTokenAllocator);
nsCParserNode* theNode=mNodeAllocator.CreateNode(aToken, mTokenAllocator);
if(theNode) {
STOP_TIMER();
@ -2394,6 +2382,7 @@ nsresult CNavDTD::CollectAttributes(nsIParserNode& aNode,eHTMLTags aTag,PRInt32
// "SELECTED/", and ">". In this case the "SELECTED/" key will be sanitized to
// a legitimate "SELECTED" key.
((CAttributeToken*)theToken)->SanitizeKey();
mLineNumber += theToken->GetNewlineCount();
#ifdef RICKG_DEBUG
WriteTokenToLog(theToken);
@ -2419,78 +2408,75 @@ nsresult CNavDTD::CollectAttributes(nsIParserNode& aNode,eHTMLTags aTag,PRInt32
* @param holds the number of skipped content elements encountered
* @return Error condition.
*/
nsresult CNavDTD::CollectSkippedContent(nsIParserNode& aNode,PRInt32 &aCount) {
NS_IMETHODIMP
CNavDTD::CollectSkippedContent(PRInt32 aTag, nsAString& aContent, PRInt32 &aLineNo) {
eHTMLTags theNodeTag=(eHTMLTags)aNode.GetNodeType();
NS_ASSERTION(aTag >= eHTMLTag_unknown && aTag <= NS_HTML_TAG_MAX, "tag array out of bounds");
int aIndex=0;
int aMax=mSkippedContent.GetSize();
aContent.Truncate();
NS_ASSERTION(eHTMLTag_unknown != gHTMLElements[aTag].mSkipTarget, "cannot collect content for this tag");
if (eHTMLTag_unknown == gHTMLElements[aTag].mSkipTarget) {
// This tag doesn't support skipped content.
aLineNo = -1;
return NS_OK;
}
aLineNo = mLineNumber;
// XXX rickg This linefeed conversion stuff should be moved out of
// the parser and into the form element code
PRBool aMustConvertLinebreaks = PR_FALSE;
PRBool mustConvertLinebreaks = PR_FALSE;
mScratch.Truncate();
nsCParserNode* theNode=NS_STATIC_CAST(nsCParserNode*,&aNode);
if(theNode) {
theNode->SetSkippedContent(mScratch); //this guarantees us some skipped content storage.
for(aIndex=0;aIndex<aMax;aIndex++){
CHTMLToken* theNextToken=(CHTMLToken*)mSkippedContent.PopFront();
eHTMLTokenTypes theTokenType=(eHTMLTokenTypes)theNextToken->GetTokenType();
PRInt32 i = 0;
PRInt32 tagCount = mSkippedContent.GetSize();
for (i = 0; i< tagCount; i++){
CHTMLToken* theNextToken = (CHTMLToken*)mSkippedContent.PopFront();
if (theNextToken) {
eHTMLTokenTypes theTokenType = (eHTMLTokenTypes)theNextToken->GetTokenType();
// Dont worry about attributes here because it's already stored in
// the start token as mTrailing content and will get appended in
// start token's GetSource();
if(eToken_attribute!=theTokenType) {
if (eToken_attribute!=theTokenType) {
if ((eToken_entity==theTokenType) &&
((eHTMLTag_textarea==theNodeTag) || (eHTMLTag_title==theNodeTag))) {
((eHTMLTag_textarea == aTag) || (eHTMLTag_title == aTag))) {
mScratch.Truncate();
((CEntityToken*)theNextToken)->TranslateToUnicodeStr(mScratch);
// since this is an entity, we know that it's only one character.
// check to see if it's a CR, in which case we'll need to do line
// termination conversion at the end.
if(!mScratch.IsEmpty()){
aMustConvertLinebreaks |= (mScratch[0] == kCR);
theNode->mSkippedContent->Append(mScratch);
if (!mScratch.IsEmpty()){
mustConvertLinebreaks |= (mScratch[0] == kCR);
aContent.Append(mScratch);
}
else {
// We thought it was an entity but it is not! - bug 79492
theNode->mSkippedContent->Append(PRUnichar('&'));
theNode->mSkippedContent->Append(theNextToken->GetStringValue());
aContent.Append(PRUnichar('&'));
aContent.Append(theNextToken->GetStringValue());
}
}
else theNextToken->AppendSource(*theNode->mSkippedContent);
else theNextToken->AppendSourceTo(aContent);
}
IF_FREE(theNextToken, mTokenAllocator);
}
// if the string contained CRs (hence is either CR, or CRLF terminated)
// we need to convert line breaks
if (aMustConvertLinebreaks)
{
/*
PRInt32 offset;
while ((offset = aNode.mSkippedContent.Find("\r\n")) != kNotFound)
aNode.mSkippedContent.Cut(offset, 1); // remove the CR
// now replace remaining CRs with LFs
aNode.mSkippedContent.ReplaceChar("\r", kNewLine);
*/
#if 1
nsLinebreakConverter::ConvertStringLineBreaks(*theNode->mSkippedContent,
nsLinebreakConverter::eLinebreakAny, nsLinebreakConverter::eLinebreakContent);
#endif
}
// Let's hope that this does not hamper the PERFORMANCE!!
mLineNumber += theNode->mSkippedContent->CountChar(kNewLine);
IF_FREE(theNextToken, mTokenAllocator);
}
// if the string contained CRs (hence is either CR, or CRLF terminated)
// we need to convert line breaks
if (mustConvertLinebreaks)
{
InPlaceConvertLineEndings(aContent);
}
// Note: TEXTAREA content is PCDATA and hence the newlines are already accounted for.
mLineNumber += (aTag != eHTMLTag_textarea) ? aContent.CountChar(kNewLine) : 0;
return NS_OK;
}
/***********************************************************************************
The preceeding tables determine the set of elements each tag can contain...
***********************************************************************************/
@ -3004,7 +2990,7 @@ nsresult CNavDTD::CloseTransientStyles(eHTMLTags aChildTag){
for(theTagPos=mBodyContext->mOpenStyles;theTagPos>0;theTagPos--){
eHTMLTags theTag=GetTopNode();
CStartToken token(theTag);
nsCParserNode theNode(&token,mLineNumber,0 /*stack token*/);
nsCParserNode theNode(&token, 0 /*stack token*/);
token.SetTypeID(theTag);
result=CloseContainer(theNode,theTag,PR_FALSE);
}
@ -3849,7 +3835,12 @@ nsresult CNavDTD::AddHeadLeaf(nsIParserNode *aNode){
if(NS_OK==result) {
if(eHTMLTag_title==theTag) {
const nsString& theString=aNode->GetSkippedContent();
nsAutoString theString;
PRInt32 lineNo = 0;
result = CollectSkippedContent(eHTMLTag_title, theString, lineNo);
NS_ENSURE_SUCCESS(result, result);
PRInt32 theLen=theString.Length();
CBufDescriptor theBD(theString.get(), PR_TRUE, theLen+1, theLen);
nsAutoString theString2(theBD);
@ -3937,22 +3928,6 @@ nsresult CNavDTD::CreateContextStackFor(eHTMLTags aChildTag){
return result;
}
/**
* Retrieve the preferred tokenizer for use by this DTD.
* @update gess12/28/98
* @param none
* @return ptr to tokenizer
*/
NS_IMETHODIMP
CNavDTD::GetTokenizer(nsITokenizer*& aTokenizer) {
nsresult result=NS_OK;
if(!mTokenizer) {
result=NS_NewHTMLTokenizer(&mTokenizer,mDTDMode,mDocType,mParserCommand);
}
aTokenizer=mTokenizer;
return result;
}
/**
*
* @update gess5/18/98

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

@ -330,6 +330,15 @@ public:
nsresult DoFragment(PRBool aFlag);
nsresult PushIntoMisplacedStack(CToken* aToken)
{
NS_ENSURE_ARG_POINTER(aToken);
aToken->SetNewlineCount(0); // Note: We have already counted the newlines for these tokens
mMisplacedContent.Push(aToken);
return NS_OK;
}
protected:
nsresult CollectAttributes(nsIParserNode& aNode,eHTMLTags aTag,PRInt32 aCount);
@ -348,7 +357,7 @@ protected:
nsDTDContext* mBodyContext;
nsDTDContext* mTempContext;
nsParser* mParser;
nsITokenizer* mTokenizer;
nsITokenizer* mTokenizer; // weak
nsString mFilename;
nsString mScratch; //used for various purposes; non-persistent

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

@ -210,8 +210,7 @@ COtherDTD::~COtherDTD(){
delete mNodeAllocator;
mNodeAllocator=nsnull;
}
NS_IF_RELEASE(mTokenizer);
NS_IF_RELEASE(mSink);
}
@ -324,7 +323,9 @@ COtherDTD::CanParse(CParserContext& aParserContext, const nsString& aBuffer,
* @param aSink
* @return error code (almost always 0)
*/
nsresult COtherDTD::WillBuildModel( const CParserContext& aParserContext,nsIContentSink* aSink){
nsresult COtherDTD::WillBuildModel(const CParserContext& aParserContext,
nsITokenizer* aTokenizer,
nsIContentSink* aSink){
nsresult result=NS_OK;
mFilename=aParserContext.mScanner->GetFilename();
@ -334,6 +335,7 @@ nsresult COtherDTD::WillBuildModel( const CParserContext& aParserContext,nsICon
mHasOpenScript=PR_FALSE;
mDTDMode=aParserContext.mDTDMode;
mParserCommand=aParserContext.mParserCommand;
mTokenizer = aTokenizer;
if((!aParserContext.mPrevContext) && (aSink)) {
@ -488,6 +490,18 @@ COtherDTD::Terminate()
mDTDState = NS_ERROR_HTMLPARSER_STOPPARSING;
}
NS_IMETHODIMP_(PRInt32)
COtherDTD::GetType()
{
return NS_IPARSER_FLAG_HTML;
}
NS_IMETHODIMP
COtherDTD::CollectSkippedContent(PRInt32 aTag, nsAString& aContent, PRInt32 &aLineNo)
{
return NS_OK;
}
/**
* This big dispatch method is used to route token handler calls to the right place.
* What's wrong with it? This table, and the dispatch methods themselves need to be
@ -682,7 +696,7 @@ nsresult COtherDTD::HandleStartToken(CToken* aToken) {
//Begin by gathering up attributes...
nsresult result=NS_OK;
nsCParserNode* theNode=mNodeAllocator->CreateNode(aToken,mLineNumber,mTokenAllocator);
nsCParserNode* theNode=mNodeAllocator->CreateNode(aToken, mTokenAllocator);
if(theNode) {
eHTMLTags theChildTag=(eHTMLTags)aToken->GetTypeID();
@ -695,7 +709,7 @@ nsresult COtherDTD::HandleStartToken(CToken* aToken) {
result=WillHandleStartTag(aToken,theChildTag,*theNode);
if(NS_OK==result) {
mLineNumber += aToken->mNewlineCount;
mLineNumber += aToken->GetNewlineCount();
PRBool theTagWasHandled=PR_FALSE;
@ -769,7 +783,7 @@ nsresult COtherDTD::HandleEndToken(CToken* aToken) {
}
CElement* theElement=gElementTable->mElements[theParent];
if(theElement) {
nsCParserNode* theNode=mNodeAllocator->CreateNode(aToken,mLineNumber,mTokenAllocator);
nsCParserNode* theNode=mNodeAllocator->CreateNode(aToken, mTokenAllocator);
if(theNode) {
result=theElement->HandleEndToken(theNode,theChildTag,mBodyContext,mSink);
IF_FREE(theNode, mNodeAllocator);
@ -864,7 +878,7 @@ nsresult COtherDTD::HandleEntityToken(CToken* aToken) {
eHTMLTags theParent=mBodyContext->Last();
CElement* theElement=gElementTable->mElements[theParent];
if(theElement) {
nsCParserNode theNode(aToken,mLineNumber,0);
nsCParserNode theNode(aToken, 0);
result=theElement->HandleStartToken(&theNode,eHTMLTag_text,mBodyContext,mSink);
}
}
@ -980,23 +994,6 @@ PRBool COtherDTD::IsInlineElement(PRInt32 aChildID,PRInt32 aParentID) const {
PRBool COtherDTD::IsContainer(PRInt32 aTag) const {
return gElementTable->mElements[eHTMLTags(aTag)]->IsContainer();
}
/**
* Retrieve the preferred tokenizer for use by this DTD.
* @update gess12/28/98
* @param none
* @return ptr to tokenizer
*/
nsresult COtherDTD::GetTokenizer(nsITokenizer*& aTokenizer) {
nsresult result=NS_OK;
if(!mTokenizer) {
result=NS_NewHTMLTokenizer(&mTokenizer,mDTDMode,mDocType,mParserCommand);
}
aTokenizer=mTokenizer;
return result;
}
/**
*

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

@ -175,7 +175,7 @@ protected:
nsString mFilename;
PRInt32 mLineNumber;
nsParser* mParser;
nsITokenizer* mTokenizer;
nsITokenizer* mTokenizer; // weak
nsTokenAllocator* mTokenAllocator;
nsNodeAllocator* mNodeAllocator;
PRBool mHasOpenScript;

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

@ -263,18 +263,17 @@ public:
}
nsresult AutoGenerateStructure(eHTMLTags *aTagList,nsDTDContext* aContext,nsIHTMLContentSink* aSink) {
PRInt32 theLineNumber=0;
nsresult result=NS_OK;
CStartToken theToken(*aTagList);
nsCParserNode theNode(&theToken,theLineNumber,0 /*stack token*/);
nsCParserNode theNode(&theToken, 0 /*stack token*/);
result=OpenContainer(&theNode,*aTagList,aContext,aSink);
if(eHTMLTag_unknown!=*(aTagList+1)) {
AutoGenerateStructure(++aTagList,aContext,aSink);
}
CEndToken theEndToken(*aTagList--);
nsCParserNode theEndNode(&theEndToken,theLineNumber,0 /*stack token*/);
nsCParserNode theEndNode(&theEndToken, 0 /*stack token*/);
result=CloseContainer(&theEndNode,*aTagList,aContext,aSink);
return result;
@ -825,7 +824,7 @@ public:
if(aContext->mTableStates) {
if(aContext->mTableStates->CanOpenTBody()) {
CToken* theToken=(CStartToken*)aContext->mTokenAllocator->CreateTokenOfType(eToken_start,eHTMLTag_tbody);
nsCParserNode* theNode=aContext->mNodeAllocator->CreateNode(theToken,0,0);
nsCParserNode* theNode=aContext->mNodeAllocator->CreateNode(theToken, 0);
result=HandleStartToken(theNode,eHTMLTag_tbody,aContext,aSink);
}
@ -1023,8 +1022,7 @@ public:
aContext->IncrementCounter(theGrandParentTag,*theNode,theNumber);
CTextToken theToken(theNumber);
PRInt32 theLineNumber=0;
nsCParserNode theNewNode(&theToken,theLineNumber,0 /*stack token*/);
nsCParserNode theNewNode(&theToken, 0 /*stack token*/);
*theNode = theNewNode;
#endif
result=aSink->AddLeaf(*theNode);
@ -1227,13 +1225,12 @@ public:
if(aNode) {
#if 0
CStartToken theToken(aTag);
PRInt32 theLineNumber=0;
nsCParserNode theNode(&theToken,theLineNumber);
nsCParserNode theNode(&theToken);
theNode.SetSkippedContent(mText);
result=aSink->AddLeaf(theNode);
#endif
nsCParserNode *theNode=(nsCParserNode*)aNode;
theNode->SetSkippedContent(mText);
//theNode->SetSkippedContent(mText); XXX why do we need this?
result=aSink->AddLeaf(*theNode);
}
mText.Truncate(0);
@ -1816,7 +1813,7 @@ public:
//let's auto open the body
CToken* theToken=(CStartToken*)aContext->mTokenAllocator->CreateTokenOfType(eToken_start,eHTMLTag_body);
nsCParserNode* theNode=aContext->mNodeAllocator->CreateNode(theToken,0,0);
nsCParserNode* theNode=aContext->mNodeAllocator->CreateNode(theToken, 0);
result=theBody->HandleStartToken(theNode,eHTMLTag_body,aContext,aSink);

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

@ -40,6 +40,8 @@
#include "CParserContext.h"
#include "nsToken.h"
#include "prenv.h"
#include "nsHTMLTokenizer.h"
#include "nsExpatDriver.h"
MOZ_DECL_CTOR_COUNTER(CParserContext)
@ -70,7 +72,8 @@ CParserContext::CParserContext(nsScanner* aScanner,
mAutoDetectStatus=aStatus;
mTransferBuffer=0;
mDTD=aDTD;
NS_IF_ADDREF(mDTD);
NS_IF_ADDREF(mDTD);
mTokenizer = 0;
mTransferBufferSize=eTransferBufferSize;
mStreamListenerState=eNone;
mMultipart=PR_TRUE;
@ -103,6 +106,9 @@ CParserContext::CParserContext(const CParserContext &aContext) : mMimeType() {
mDTD=aContext.mDTD;
NS_IF_ADDREF(mDTD);
mTokenizer = aContext.mTokenizer;
NS_IF_ADDREF(mTokenizer);
mTransferBufferSize=eTransferBufferSize;
mStreamListenerState=aContext.mStreamListenerState;
mMultipart=aContext.mMultipart;
@ -132,6 +138,7 @@ CParserContext::~CParserContext(){
NS_IF_RELEASE(mDTD);
NS_IF_RELEASE(mListener);
NS_IF_RELEASE(mTokenizer);
//Remember that it's ok to simply ingore the PrevContext.
@ -149,11 +156,28 @@ void CParserContext::SetMimeType(const nsACString& aMimeType){
if(mMimeType.Equals(NS_LITERAL_CSTRING(kHTMLTextContentType)))
mDocType=eHTML_Strict;
else if (mMimeType.Equals(NS_LITERAL_CSTRING(kXMLTextContentType)) ||
mMimeType.Equals(NS_LITERAL_CSTRING(kXMLApplicationContentType)) ||
else if (mMimeType.Equals(NS_LITERAL_CSTRING(kXMLTextContentType)) ||
mMimeType.Equals(NS_LITERAL_CSTRING(kXMLApplicationContentType)) ||
mMimeType.Equals(NS_LITERAL_CSTRING(kXHTMLApplicationContentType)) ||
mMimeType.Equals(NS_LITERAL_CSTRING(kXULTextContentType)) ||
mMimeType.Equals(NS_LITERAL_CSTRING(kRDFTextContentType)) ||
mMimeType.Equals(NS_LITERAL_CSTRING(kXIFTextContentType)))
mMimeType.Equals(NS_LITERAL_CSTRING(kXULTextContentType)) ||
mMimeType.Equals(NS_LITERAL_CSTRING(kRDFTextContentType)))
mDocType=eXML;
}
nsresult
CParserContext::GetTokenizer(PRInt32 aType, nsITokenizer*& aTokenizer) {
nsresult result = NS_OK;
if(!mTokenizer) {
if (aType == NS_IPARSER_FLAG_HTML || mParserCommand == eViewSource) {
result = NS_NewHTMLTokenizer(&mTokenizer,mDTDMode,mDocType,mParserCommand);
}
else if (aType == NS_IPARSER_FLAG_XML)
{
result = CallQueryInterface(mDTD, &mTokenizer);
}
}
aTokenizer = mTokenizer;
return result;
}

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

@ -77,6 +77,7 @@ public:
CParserContext( const CParserContext& aContext);
~CParserContext();
nsresult GetTokenizer(PRInt32 aType, nsITokenizer*& aTokenizer);
void SetMimeType(const nsACString& aMimeType);
nsCOMPtr<nsIRequest> mRequest; // provided by necko to differnciate different input streams
@ -85,6 +86,7 @@ public:
nsIRequestObserver* mListener;
char* mTransferBuffer;
void* mKey;
nsITokenizer* mTokenizer;
CParserContext* mPrevContext;
nsScanner* mScanner;

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

@ -1383,7 +1383,8 @@ nsNodeAllocator::~nsNodeAllocator() {
#endif
}
nsCParserNode* nsNodeAllocator::CreateNode(CToken* aToken,PRInt32 aLineNumber,nsTokenAllocator* aTokenAllocator) {
nsCParserNode* nsNodeAllocator::CreateNode(CToken* aToken,
nsTokenAllocator* aTokenAllocator) {
nsCParserNode* result=0;
#ifdef HEAP_ALLOCATED_NODES
@ -1395,10 +1396,10 @@ nsCParserNode* nsNodeAllocator::CreateNode(CToken* aToken,PRInt32 aLineNumber,ns
result=NS_STATIC_CAST(nsCParserNode*,mSharedNodes.Pop());
if(result) {
result->Init(aToken,aLineNumber,aTokenAllocator,this);
result->Init(aToken, aTokenAllocator,this);
}
else{
result=nsCParserNode::Create(aToken,aLineNumber,aTokenAllocator,this);
result=nsCParserNode::Create(aToken, aTokenAllocator,this);
#ifdef DEBUG_TRACK_NODES
mCount++;
AddNode(NS_STATIC_CAST(nsCParserNode*,result));
@ -1406,7 +1407,7 @@ nsCParserNode* nsNodeAllocator::CreateNode(CToken* aToken,PRInt32 aLineNumber,ns
IF_HOLD(result);
}
#else
result=nsCParserNode::Create(aToken,aLineNumber,aTokenAllocator,this);
result=nsCParserNode::Create(aToken, aTokenAllocator,this);
IF_HOLD(result);
#endif
return result;

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

@ -303,7 +303,7 @@ public:
nsNodeAllocator();
virtual ~nsNodeAllocator();
virtual nsCParserNode* CreateNode(CToken* aToken=nsnull,PRInt32 aLineNumber=1,nsTokenAllocator* aTokenAllocator=0);
virtual nsCParserNode* CreateNode(CToken* aToken=nsnull, nsTokenAllocator* aTokenAllocator=0);
nsFixedSizeAllocator& GetArenaPool() { return mNodePool; }
@ -646,6 +646,80 @@ inline PRBool HasOptionalEndTag(eHTMLTags aTag) {
return FindTagInSet(aTag,gHasOptionalEndTags,sizeof(gHasOptionalEndTags)/sizeof(eHTMLTag_body));
}
static void
InPlaceConvertLineEndings( nsAString& aString )
{
// go from '\r\n' or '\r' to '\n'
nsAString::iterator iter;
aString.BeginWriting(iter);
PRUnichar* S = iter.get();
size_t N = iter.size_forward();
// this fragment must be the entire string because
// (a) no multi-fragment string is writable, so only an illegal cast could give us one, and
// (b) else we would have to do more work (watching for |to| to fall off the end)
NS_ASSERTION(aString.Length() == N, "You cheated... multi-fragment strings are never writable!");
// we scan/convert in two phases (but only one pass over the string)
// until we have to skip a character, we only need to touch end-of-line chars
// after that, we'll have to start moving every character we want to keep
// use array indexing instead of pointers, because compilers optimize that better
// this first loop just converts line endings... no characters get moved
size_t i = 0;
PRBool just_saw_cr = PR_FALSE;
for ( ; i < N; ++i )
{
// if it's something we need to convert...
if ( S[i] == '\r' )
{
S[i] = '\n';
just_saw_cr = PR_TRUE;
}
else
{
// else, if it's something we need to skip...
// i.e., a '\n' immediately following a '\r',
// then we need to start moving any character we want to keep
// and we have a second loop for that, so get out of this one
if ( S[i] == '\n' && just_saw_cr )
break;
just_saw_cr = PR_FALSE;
}
}
// this second loop handles the rest of the buffer, moving characters down
// _and_ converting line-endings as it goes
// start the loop at |from = i| so that that |just_saw_cr| gets cleared automatically
size_t to = i;
for ( size_t from = i; from < N; ++from )
{
// if it's something we need to convert...
if ( S[from] == '\r' )
{
S[to++] = '\n';
just_saw_cr = PR_TRUE;
}
else
{
// else, if it's something we need to copy...
// i.e., NOT a '\n' immediately following a '\r'
if ( S[from] != '\n' || !just_saw_cr )
S[to++] = S[from];
just_saw_cr = PR_FALSE;
}
}
// if we chopped characters out of the string, we need to shorten it logically
if ( to < N )
aString.SetLength(to);
}
#endif

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

@ -822,7 +822,8 @@ nsExpatDriver::CanParse(CParserContext& aParserContext,
}
NS_IMETHODIMP
nsExpatDriver::WillBuildModel(const CParserContext& aParserContext,
nsExpatDriver::WillBuildModel(const CParserContext& aParserContext,
nsITokenizer* aTokenizer,
nsIContentSink* aSink)
{
@ -882,12 +883,6 @@ nsExpatDriver::DidBuildModel(nsresult anErrorCode,
return result;
}
NS_IMETHODIMP nsExpatDriver::GetTokenizer(nsITokenizer*& aTokenizer)
{
aTokenizer = this;
return NS_OK;
}
NS_IMETHODIMP
nsExpatDriver::WillTokenize(PRBool aIsFinalChunk,
nsTokenAllocator* aTokenAllocator)
@ -926,8 +921,20 @@ nsExpatDriver::Terminate()
mInternalState = NS_ERROR_HTMLPARSER_STOPPARSING;
}
NS_IMETHODIMP_(PRInt32)
nsExpatDriver::GetType()
{
return NS_IPARSER_FLAG_XML;
}
/*************************** Unused methods ***************************************/
NS_IMETHODIMP
nsExpatDriver::CollectSkippedContent(PRInt32 aTag, nsAString& aContent, PRInt32 &aLineNo)
{
return NS_OK;
}
NS_IMETHODIMP_(CToken*)
nsExpatDriver::PushTokenFront(CToken* aToken)
{

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

@ -607,7 +607,9 @@ nsresult nsHTMLTokenizer::ConsumeTag(PRUnichar aChar,CToken*& aToken,nsScanner&
* @param aLeadingWS: contains ws chars that preceeded the first attribute
* @return
*/
nsresult nsHTMLTokenizer::ConsumeAttributes(PRUnichar aChar,CStartToken* aToken,nsScanner& aScanner) {
nsresult nsHTMLTokenizer::ConsumeAttributes(PRUnichar aChar,
CToken* aToken,
nsScanner& aScanner) {
PRBool done=PR_FALSE;
nsresult result=NS_OK;
PRInt16 theAttrCount=0;
@ -649,20 +651,24 @@ nsresult nsHTMLTokenizer::ConsumeAttributes(PRUnichar aChar,CStartToken* aToken,
}
}//if
#ifdef DEBUG
if(NS_SUCCEEDED(result)){
result=aScanner.SkipWhitespace();
if(NS_SUCCEEDED(result)) {
result=aScanner.Peek(aChar);
if(NS_SUCCEEDED(result)) {
if(aChar==kGreaterThan) { //you just ate the '>'
aScanner.GetChar(aChar); //skip the '>'
done=PR_TRUE;
}
else if(aChar==kLessThan) {
done=PR_TRUE;
}
}//if
}
PRInt32 newline = 0;
result = aScanner.SkipWhitespace(newline);
NS_ASSERTION(newline == 0, "CAttribute::Consume() failed to collect all the newlines!");
}
#endif
if (NS_SUCCEEDED(result)) {
result = aScanner.Peek(aChar);
if (NS_SUCCEEDED(result)) {
if (aChar == kGreaterThan) { //you just ate the '>'
aScanner.GetChar(aChar); //skip the '>'
done = PR_TRUE;
}
else if(aChar == kLessThan) {
done = PR_TRUE;
}
}//if
}//if
}//while
@ -706,51 +712,28 @@ nsresult nsHTMLTokenizer::ConsumeStartTag(PRUnichar aChar,CToken*& aToken,nsScan
if(NS_SUCCEEDED(result)) {
AddToken(aToken,result,&mTokenDeque,theAllocator);
NS_ENSURE_SUCCESS(result, result);
eHTMLTags theTag=(eHTMLTags)aToken->GetTypeID();
//Good. Now, let's see if the next char is ">".
//If so, we have a complete tag, otherwise, we have attributes.
PRBool theTagHasAttributes=PR_FALSE;
nsReadingIterator<PRUnichar> start, end;
if(NS_OK==result) {
if (mFlags & NS_IPARSER_FLAG_VIEW_SOURCE) {
result = aScanner.ReadWhitespace(start, end);
}
else {
result = aScanner.SkipWhitespace();
}
aToken->mNewlineCount += aScanner.GetNewlinesSkipped();
if(NS_OK==result) {
result=aScanner.Peek(aChar);
if(NS_OK==result) {
if(kGreaterThan!=aChar) { //look for '>'
//push that char back, since we apparently have attributes...
theTagHasAttributes=PR_TRUE;
} //if
else {
aScanner.GetChar(aChar);
}
} //if
}//if
}
CStartToken* theStartToken=NS_STATIC_CAST(CStartToken*,aToken);
if(theTagHasAttributes) {
if (mFlags & NS_IPARSER_FLAG_VIEW_SOURCE) {
// Since we conserve whitespace in view-source mode,
// go back to the beginning of the whitespace section
// and let the first attribute grab it.
aScanner.SetPosition(start, PR_FALSE, PR_TRUE);
}
result=ConsumeAttributes(aChar,theStartToken,aScanner);
}
//Good. Now, let's see if the next char is ">".
//If so, we have a complete tag, otherwise, we have attributes.
result = aScanner.Peek(aChar);
NS_ENSURE_SUCCESS(result, result);
if(kGreaterThan != aChar) { //look for '>'
result = ConsumeAttributes(aChar, aToken, aScanner);
} //if
else {
aScanner.GetChar(aChar);
}
/* Now that that's over with, we have one more problem to solve.
In the case that we just read a <SCRIPT> or <STYLE> tags, we should go and
consume all the content itself.
*/
if(NS_SUCCEEDED(result)) {
CStartToken* theStartToken = NS_STATIC_CAST(CStartToken*,aToken);
//XXX - Find a better soution to record content
//Added _plaintext to fix bug 46054.
if((theTag == eHTMLTag_textarea ||
@ -825,7 +808,19 @@ nsresult nsHTMLTokenizer::ConsumeEndTag(PRUnichar aChar,CToken*& aToken,nsScanne
if(aToken) {
result= aToken->Consume(aChar,aScanner,mFlags); //tell new token to finish consuming text...
AddToken(aToken,result,&mTokenDeque,theAllocator);
NS_ENSURE_SUCCESS(result, result);
result = aScanner.Peek(aChar);
NS_ENSURE_SUCCESS(result, result);
if(kGreaterThan != aChar) {
result = ConsumeAttributes(aChar, aToken, aScanner);
NS_ENSURE_SUCCESS(result, result);
}
else {
aScanner.GetChar(aChar);
}
if(NS_SUCCEEDED(result)) {
eHTMLTags theTag=(eHTMLTags)aToken->GetTypeID();
if((theTag == eHTMLTag_textarea ||

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

@ -84,7 +84,7 @@ protected:
virtual nsresult ConsumeTag(PRUnichar aChar,CToken*& aToken,nsScanner& aScanner,PRBool& aFlushTokens);
virtual nsresult ConsumeStartTag(PRUnichar aChar,CToken*& aToken,nsScanner& aScanner,PRBool& aFlushTokens);
virtual nsresult ConsumeEndTag(PRUnichar aChar,CToken*& aToken,nsScanner& aScanner);
virtual nsresult ConsumeAttributes(PRUnichar aChar,CStartToken* aToken,nsScanner& aScanner);
virtual nsresult ConsumeAttributes(PRUnichar aChar, CToken* aToken, nsScanner& aScanner);
virtual nsresult ConsumeEntity(PRUnichar aChar,CToken*& aToken,nsScanner& aScanner);
virtual nsresult ConsumeWhitespace(PRUnichar aChar,CToken*& aToken,nsScanner& aScanner);
virtual nsresult ConsumeComment(PRUnichar aChar,CToken*& aToken,nsScanner& aScanner);

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

@ -227,6 +227,10 @@ nsresult CStartToken::Consume(PRUnichar aChar, nsScanner& aScanner,PRInt32 aFlag
mTypeID = nsHTMLTags::LookupTag(mTextValue);
}
if (NS_SUCCEEDED(result) && !(aFlag & NS_IPARSER_FLAG_VIEW_SOURCE)) {
result = aScanner.SkipWhitespace(mNewlineCount);
}
return result;
}
@ -286,7 +290,7 @@ void CStartToken::GetSource(nsString& anOutputString){
* @param result appended to the output string.
* @return nada
*/
void CStartToken::AppendSource(nsString& anOutputString){
void CStartToken::AppendSourceTo(nsAString& anOutputString){
anOutputString.Append(PRUnichar('<'));
/*
* Watch out for Bug 15204
@ -329,46 +333,30 @@ CEndToken::CEndToken(const nsAString& aName,eHTMLTags aTag) : CHTMLToken(aTag) {
* @param aFlag - contains information such as |dtd mode|view mode|doctype|etc...
* @return error result
*/
nsresult CEndToken::Consume(PRUnichar aChar, nsScanner& aScanner,PRInt32 aFlag) {
//if you're here, we've already Consumed the <! chars, and are
//ready to Consume the rest of the open tag identifier.
//Stop consuming as soon as you see a space or a '>'.
//NOTE: We don't Consume the tag attributes here, nor do we eat the ">"
nsresult result=NS_OK;
nsAutoString buffer;
PRInt32 offset;
nsresult CEndToken::Consume(PRUnichar aChar, nsScanner& aScanner,PRInt32 aFlag)
{
nsresult result = NS_OK;
if (aFlag & NS_IPARSER_FLAG_HTML) {
nsAutoString theSubstr;
result=aScanner.ReadUntil(theSubstr,kGreaterThan,PR_FALSE);
if (NS_FAILED(result)) {
return result;
}
result=aScanner.GetIdentifier(theSubstr,PR_TRUE);
NS_ENSURE_SUCCESS(result, result);
offset = theSubstr.FindCharInSet(" \r\n\t\b",0);
if (offset != kNotFound) {
theSubstr.Left(buffer, offset);
mTypeID = nsHTMLTags::LookupTag(buffer);
}
else {
mTypeID = nsHTMLTags::LookupTag(theSubstr);
}
mTypeID = (PRInt32)nsHTMLTags::LookupTag(theSubstr);
if(eHTMLTag_userdefined==mTypeID) {
mTextValue=theSubstr;
}
}
else {
mTextValue.SetLength(0);
result=aScanner.ReadUntil(mTextValue,kGreaterThan,PR_FALSE);
if (NS_FAILED(result)) {
return result;
}
mTypeID = eHTMLTag_userdefined;
result = aScanner.ReadIdentifier(mTextValue,PR_TRUE);
NS_ENSURE_SUCCESS(result, result);
mTypeID = nsHTMLTags::LookupTag(mTextValue);
}
result=aScanner.GetChar(aChar); //eat the closing '>;
if (!(aFlag & NS_IPARSER_FLAG_VIEW_SOURCE)) {
result = aScanner.SkipWhitespace(mNewlineCount);
NS_ENSURE_SUCCESS(result, result);
}
return result;
}
@ -466,7 +454,7 @@ void CEndToken::GetSource(nsString& anOutputString){
* @param result appended to the output string.
* @return nada
*/
void CEndToken::AppendSource(nsString& anOutputString){
void CEndToken::AppendSourceTo(nsAString& anOutputString){
anOutputString.Append(NS_LITERAL_STRING("</"));
if(mTextValue.Length()>0)
anOutputString.Append(mTextValue);
@ -1267,6 +1255,8 @@ nsresult CCommentToken::Consume(PRUnichar aChar, nsScanner& aScanner,PRInt32 aFl
else {
result=ConsumeComment(aScanner,mTextValue);
}
mNewlineCount = !(aFlag & NS_IPARSER_FLAG_VIEW_SOURCE) ? mTextValue.CountChar(kNewLine) : -1;
return result;
}
@ -1394,7 +1384,9 @@ nsresult CNewlineToken::Consume(PRUnichar aChar, nsScanner& aScanner,PRInt32 aFl
default:
break;
}
}
}
mNewlineCount = 1;
return result;
}
@ -1531,7 +1523,7 @@ const nsAString& CAttributeToken::GetStringValue(void)
*/
void CAttributeToken::GetSource(nsString& anOutputString){
anOutputString.Truncate();
AppendSource(anOutputString);
AppendSourceTo(anOutputString);
}
/*
@ -1541,7 +1533,7 @@ void CAttributeToken::GetSource(nsString& anOutputString){
* @param result appended to the output string.
* @return nada
*/
void CAttributeToken::AppendSource(nsString& anOutputString){
void CAttributeToken::AppendSourceTo(nsAString& anOutputString){
anOutputString.Append(mTextKey);
if(mTextValue.Length() || mHasEqualWithoutValue)
anOutputString.Append(NS_LITERAL_STRING("="));
@ -1727,10 +1719,10 @@ nsresult CAttributeToken::Consume(PRUnichar aChar, nsScanner& aScanner,PRInt32 a
nsReadingIterator<PRUnichar> wsstart, wsend;
if (aFlag & NS_IPARSER_FLAG_VIEW_SOURCE) {
result = aScanner.ReadWhitespace(wsstart, wsend);
result = aScanner.ReadWhitespace(wsstart, wsend, mNewlineCount);
}
else {
result = aScanner.SkipWhitespace();
result = aScanner.SkipWhitespace(mNewlineCount);
}
if (NS_OK==result) {
@ -1752,11 +1744,11 @@ nsresult CAttributeToken::Consume(PRUnichar aChar, nsScanner& aScanner,PRInt32 a
//now it's time to Consume the (optional) value...
if (NS_OK==result) {
if (aFlag & NS_IPARSER_FLAG_VIEW_SOURCE) {
result = aScanner.ReadWhitespace(start, wsend);
result = aScanner.ReadWhitespace(start, wsend, mNewlineCount);
aScanner.BindSubstring(mTextKey, wsstart, wsend);
}
else {
result = aScanner.SkipWhitespace();
result = aScanner.SkipWhitespace(mNewlineCount);
}
if (NS_OK==result) {
@ -1766,10 +1758,10 @@ nsresult CAttributeToken::Consume(PRUnichar aChar, nsScanner& aScanner,PRInt32 a
result=aScanner.GetChar(aChar); //skip the equal sign...
if (NS_OK==result) {
if (aFlag & NS_IPARSER_FLAG_VIEW_SOURCE) {
result = aScanner.ReadWhitespace(mTextValue);
result = aScanner.ReadWhitespace(mTextValue, mNewlineCount);
}
else {
result = aScanner.SkipWhitespace();
result = aScanner.SkipWhitespace(mNewlineCount);
}
if (NS_OK==result) {
@ -1805,10 +1797,10 @@ nsresult CAttributeToken::Consume(PRUnichar aChar, nsScanner& aScanner,PRInt32 a
}//if
if (NS_OK==result) {
if (aFlag & NS_IPARSER_FLAG_VIEW_SOURCE) {
result = aScanner.ReadWhitespace(mTextValue);
result = aScanner.ReadWhitespace(mTextValue, mNewlineCount);
}
else {
result = aScanner.SkipWhitespace();
result = aScanner.SkipWhitespace(mNewlineCount);
}
}
}//if
@ -1926,7 +1918,7 @@ PRInt32 CWhitespaceToken::GetTokenType(void) {
*/
nsresult CWhitespaceToken::Consume(PRUnichar aChar, nsScanner& aScanner,PRInt32 aFlag) {
mTextValue.Assign(aChar);
nsresult result=aScanner.ReadWhitespace(mTextValue);
nsresult result=aScanner.ReadWhitespace(mTextValue, mNewlineCount);
if(NS_OK==result) {
mTextValue.StripChar(kCR);
}
@ -2237,7 +2229,7 @@ void CEntityToken::GetSource(nsString& anOutputString){
* @param result appended to the output string.
* @return nada
*/
void CEntityToken::AppendSource(nsString& anOutputString){
void CEntityToken::AppendSourceTo(nsAString& anOutputString){
anOutputString.Append(NS_LITERAL_STRING("&"));
anOutputString+=mTextValue;
//anOutputString+=";";

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

@ -41,6 +41,7 @@
#include "nsReadableUtils.h"
#include "prprf.h"
static NS_DEFINE_IID(kIContentSinkIID, NS_ICONTENT_SINK_IID);
static NS_DEFINE_IID(kIHTMLContentSinkIID, NS_IHTML_CONTENT_SINK_IID);
static NS_DEFINE_IID(kILoggingSinkIID, NS_ILOGGING_SINK_IID);
@ -197,6 +198,12 @@ nsLoggingSink::SetParser(nsIParser* aParser) {
theResult=mSink->SetParser(aParser);
}
NS_IF_RELEASE(mParser);
mParser = aParser;
NS_IF_ADDREF(mParser);
return theResult;
}
@ -610,8 +617,16 @@ nsLoggingSink::WriteAttributes(const nsIParserNode& aNode) {
}
if (0 != strchr(gSkippedContentTags, aNode.GetNodeType())) {
nsCOMPtr<nsIDTD> dtd;
mParser->GetDTD(getter_AddRefs(dtd));
NS_ENSURE_TRUE(dtd, NS_ERROR_FAILURE);
nsString theString;
PRInt32 lineNo = 0;
dtd->CollectSkippedContent(aNode.GetNodeType(), theString, lineNo);
char* content;
GetNewCString(aNode.GetSkippedContent(), &content);
GetNewCString(theString, &content);
if(content) {
PR_fprintf(mOutput, " <content value=\"");
PR_fprintf(mOutput, "%s\"/>\n", content) ;
@ -630,7 +645,14 @@ nsLoggingSink::WillWriteAttributes(const nsIParserNode& aNode)
return PR_TRUE;
}
if (0 != strchr(gSkippedContentTags, aNode.GetNodeType())) {
const nsString& content = aNode.GetSkippedContent();
nsCOMPtr<nsIDTD> dtd;
mParser->GetDTD(getter_AddRefs(dtd));
NS_ENSURE_TRUE(dtd, NS_ERROR_FAILURE);
nsString content;
PRInt32 lineNo = 0;
dtd->CollectSkippedContent(aNode.GetNodeType(), content, lineNo);
if (content.Length() > 0) {
return PR_TRUE;
}

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

@ -40,6 +40,7 @@
#define NS_LOGGING_SINK_H__
#include "nsILoggingSink.h"
#include "nsIParser.h"
class nsLoggingSink : public nsILoggingSink {
public:
@ -114,6 +115,7 @@ protected:
int mLevel;
nsIHTMLContentSink *mSink;
PRBool mAutoDeleteOutput;
nsIParser* mParser;
};
#endif

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

@ -1222,7 +1222,9 @@ nsresult nsParser::WillBuildModel(nsString& aFilename){
}
if(PR_TRUE==FindSuitableDTD(*mParserContext,theBuffer)) {
mParserContext->mDTD->WillBuildModel( *mParserContext,mSink);
nsITokenizer* tokenizer;
mParserContext->GetTokenizer(mParserContext->mDTD->GetType(), tokenizer);
mParserContext->mDTD->WillBuildModel(*mParserContext, tokenizer, mSink);
}//if
}//if
}
@ -1548,10 +1550,10 @@ nsresult nsParser::Parse(const nsAString& aSourceBuffer, void* aKey,
return result;
}
nsParser* me = this;
// Maintain a reference to ourselves so we don't go away
// till we're completely done.
NS_ADDREF(me);
nsCOMPtr<nsIParser> kungFuDeathGrip(this);
if(aSourceBuffer.Length() || mUnusedInput.Length()) {
@ -1567,57 +1569,55 @@ nsresult nsParser::Parse(const nsAString& aSourceBuffer, void* aKey,
if((!mParserContext) || (mParserContext->mKey!=aKey)) {
//only make a new context if we dont have one, OR if we do, but has a different context key...
nsScanner* theScanner=new nsScanner(mUnusedInput,mCharset,mCharsetSource);
nsIDTD *theDTD=0;
eAutoDetectResult theStatus=eUnknownDetect;
nsScanner* theScanner = new nsScanner(mUnusedInput,mCharset,mCharsetSource);
NS_ENSURE_TRUE(theScanner, NS_ERROR_OUT_OF_MEMORY);
nsIDTD *theDTD = 0;
eAutoDetectResult theStatus = eUnknownDetect;
if (mParserContext && mParserContext->mMimeType==aMimeType) {
NS_ASSERTION(mParserContext->mDTD,"How come the DTD is null?"); // Ref. Bug 90379
if (mParserContext->mDTD) {
mParserContext->mDTD->CreateNewInstance(&theDTD); // To fix 32263
if (mParserContext) {
// To fix bug 32263 we used create a new instance of the DTD!.
// All we need is a new tokenizer which now gets created with
// a parser context.
theDTD = mParserContext->mDTD;
theStatus=mParserContext->mAutoDetectStatus;
//added this to fix bug 32022.
}
}
pc=new CParserContext(theScanner,aKey, mCommand,0,theDTD,theStatus,aLastCall);
pc = new CParserContext(theScanner, aKey, mCommand, 0, theDTD, theStatus, aLastCall);
NS_ENSURE_TRUE(pc, NS_ERROR_OUT_OF_MEMORY);
if(pc && theScanner) {
PushContext(*pc);
pc->mMultipart=!aLastCall; //by default
if (pc->mPrevContext) {
pc->mMultipart |= pc->mPrevContext->mMultipart; //if available
}
// start fix bug 40143
if(pc->mMultipart) {
pc->mStreamListenerState=eOnDataAvail;
if(pc->mScanner) pc->mScanner->SetIncremental(PR_TRUE);
}
else {
pc->mStreamListenerState=eOnStop;
if(pc->mScanner) pc->mScanner->SetIncremental(PR_FALSE);
}
// end fix for 40143
pc->mContextType=CParserContext::eCTString;
pc->SetMimeType(aMimeType);
pc->mDTDMode=aMode;
mUnusedInput.Truncate(0);
//printf("Parse(string) iterate: %i",PR_FALSE);
pc->mScanner->Append(aSourceBuffer);
// Do not interrupt document.write() - bug 95487
result = ResumeParse(PR_FALSE, PR_FALSE, PR_FALSE);
PushContext(*pc);
pc->mMultipart=!aLastCall; //by default
if (pc->mPrevContext) {
pc->mMultipart |= pc->mPrevContext->mMultipart; //if available
}
else {
NS_RELEASE(me);
return NS_ERROR_OUT_OF_MEMORY;
}
NS_IF_RELEASE(theDTD);
// start fix bug 40143
if(pc->mMultipart) {
pc->mStreamListenerState=eOnDataAvail;
if(pc->mScanner) pc->mScanner->SetIncremental(PR_TRUE);
}
else {
pc->mStreamListenerState=eOnStop;
if(pc->mScanner) pc->mScanner->SetIncremental(PR_FALSE);
}
// end fix for 40143
pc->mContextType=CParserContext::eCTString;
pc->SetMimeType(aMimeType);
pc->mDTDMode=aMode;
mUnusedInput.Truncate(0);
//printf("Parse(string) iterate: %i",PR_FALSE);
pc->mScanner->Append(aSourceBuffer);
// Do not interrupt document.write() - bug 95487
result = ResumeParse(PR_FALSE, PR_FALSE, PR_FALSE);
}
else {
mParserContext->mScanner->Append(aSourceBuffer);
@ -1631,7 +1631,7 @@ nsresult nsParser::Parse(const nsAString& aSourceBuffer, void* aKey,
}
}
}//if
NS_RELEASE(me);
return result;
}
@ -1841,33 +1841,33 @@ nsresult nsParser::ResumeParse(PRBool allowIteration, PRBool aIsFinalChunk, PRBo
* @return error code -- 0 if ok, non-zero if error.
*/
nsresult nsParser::BuildModel() {
//nsDequeIterator e=mParserContext->mTokenDeque.End();
CParserContext* theRootContext = mParserContext;
nsITokenizer* theTokenizer = 0;
// if(!mParserContext->mCurrentPos)
// mParserContext->mCurrentPos=new nsDequeIterator(mParserContext->mTokenDeque.Begin());
nsresult result = NS_OK;
if (mParserContext) {
PRInt32 type = mParserContext->mDTD ? mParserContext->mDTD->GetType() : NS_IPARSER_FLAG_HTML;
mParserContext->GetTokenizer(type, theTokenizer);
}
if (theTokenizer) {
//Get the root DTD for use in model building...
CParserContext* theRootContext=mParserContext;
nsITokenizer* theTokenizer=0;
nsresult result = (mParserContext->mDTD)? mParserContext->mDTD->GetTokenizer(theTokenizer):NS_OK;
if(theTokenizer){
while(theRootContext->mPrevContext) {
theRootContext=theRootContext->mPrevContext;
while (theRootContext->mPrevContext) {
theRootContext = theRootContext->mPrevContext;
}
nsIDTD* theRootDTD=theRootContext->mDTD;
if(theRootDTD) {
nsIDTD* theRootDTD = theRootContext->mDTD;
if (theRootDTD) {
MOZ_TIMER_START(mDTDTime);
result=theRootDTD->BuildModel(this,theTokenizer,mTokenObserver,mSink);
result = theRootDTD->BuildModel(this, theTokenizer, mTokenObserver, mSink);
MOZ_TIMER_STOP(mDTDTime);
}
}
else{
mInternalState=result=NS_ERROR_HTMLPARSER_BADTOKENIZER;
mInternalState = result = NS_ERROR_HTMLPARSER_BADTOKENIZER;
}
return result;
}
@ -1879,12 +1879,14 @@ nsresult nsParser::BuildModel() {
* @param
* @return
*/
nsITokenizer* nsParser::GetTokenizer(void) {
nsITokenizer* theTokenizer=0;
if(mParserContext && mParserContext->mDTD) {
mParserContext->mDTD->GetTokenizer(theTokenizer);
nsresult nsParser::GetTokenizer(nsITokenizer*& aTokenizer) {
nsresult result = NS_OK;
aTokenizer = nsnull;
if(mParserContext) {
PRInt32 type = mParserContext->mDTD ? mParserContext->mDTD->GetType() : NS_IPARSER_FLAG_HTML;
result = mParserContext->GetTokenizer(type, aTokenizer);
}
return theTokenizer;
return result;
}
/*******************************************************************
@ -2446,7 +2448,12 @@ nsresult nsParser::OnStopRequest(nsIRequest *request, nsISupports* aContext,
*/
PRBool nsParser::WillTokenize(PRBool aIsFinalChunk){
nsITokenizer* theTokenizer=0;
nsresult result = (mParserContext->mDTD)? mParserContext->mDTD->GetTokenizer(theTokenizer):NS_OK;
nsresult result = NS_OK;
if (mParserContext) {
PRInt32 type = mParserContext->mDTD ? mParserContext->mDTD->GetType() : NS_IPARSER_FLAG_HTML;
mParserContext->GetTokenizer(type, theTokenizer);
}
if (theTokenizer) {
result = theTokenizer->WillTokenize(aIsFinalChunk,&mTokenAllocator);
}
@ -2466,16 +2473,23 @@ nsresult nsParser::Tokenize(PRBool aIsFinalChunk){
nsITokenizer* theTokenizer = 0;
nsresult result =
(mParserContext && mParserContext->mDTD)? mParserContext->mDTD->GetTokenizer(theTokenizer) : NS_OK;
nsresult result = NS_OK;
if (theTokenizer){
if (mParserContext) {
PRInt32 type = mParserContext->mDTD ? mParserContext->mDTD->GetType() : NS_IPARSER_FLAG_HTML;
mParserContext->GetTokenizer(type, theTokenizer);
}
if (theTokenizer) {
if (mFlags & NS_PARSER_FLAG_FLUSH_TOKENS) {
// For some reason tokens didn't get flushed ( probably
// the parser got blocked before all the tokens in the
// stack got handled ). Flush 'em now. Ref. bug 104856
if (theTokenizer->GetCount() == 0) {
mFlags &= ~NS_PARSER_FLAG_FLUSH_TOKENS; // reset since the tokens have been flushed.
// Resume tokenization for the rest of the document
// since all the tokens in the tokenizer got flushed.
result = Tokenize(aIsFinalChunk);
}
}
else {
@ -2534,7 +2548,11 @@ PRBool nsParser::DidTokenize(PRBool aIsFinalChunk){
PRBool result=PR_TRUE;
nsITokenizer* theTokenizer=0;
nsresult rv = (mParserContext->mDTD)? mParserContext->mDTD->GetTokenizer(theTokenizer):NS_OK;
nsresult rv = NS_OK;
if (mParserContext) {
PRInt32 type = mParserContext->mDTD ? mParserContext->mDTD->GetType() : NS_IPARSER_FLAG_HTML;
mParserContext->GetTokenizer(type, theTokenizer);
}
if (NS_SUCCEEDED(rv) && theTokenizer) {
result = theTokenizer->DidTokenize(aIsFinalChunk);
@ -2556,7 +2574,9 @@ void nsParser::DebugDumpSource(nsOutputStream& aStream) {
PRInt32 theIndex=-1;
nsITokenizer* theTokenizer=0;
if(NS_SUCCEEDED(mParserContext->mDTD->GetTokenizer(theTokenizer))){
PRInt32 type = mParserContext && mParserContext->mDTD ?
mParserContext->mDTD->GetType() : NS_IPARSER_FLAG_HTML;
if(NS_SUCCEEDED(mParserContext->GetTokenizer(type, theTokenizer))){
CToken* theToken;
while(nsnull != (theToken=theTokenizer->GetTokenAt(++theIndex))) {
// theToken->DebugDumpToken(out);

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

@ -297,7 +297,7 @@ class nsParser : public nsIParser,
* @param
* @return
*/
virtual nsITokenizer* GetTokenizer(void);
nsresult GetTokenizer(nsITokenizer*& aTokenizer);
/**
* Get the channel associated with this parser

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

@ -58,10 +58,8 @@ const nsString& GetEmptyString() {
* Default Constructor
*/
nsCParserNode::nsCParserNode()
: mLineNumber(1),
mToken(nsnull),
: mToken(nsnull),
mAttributes(nsnull),
mSkippedContent(nsnull),
mUseCount(0),
mGenericState(PR_FALSE),
mTokenAllocator(nsnull)
@ -79,7 +77,9 @@ nsCParserNode::nsCParserNode()
* @param aToken -- token to init internal token
* @return
*/
nsCParserNode::nsCParserNode(CToken* aToken,PRInt32 aLineNumber,nsTokenAllocator* aTokenAllocator,nsNodeAllocator* aNodeAllocator):
nsCParserNode::nsCParserNode(CToken* aToken,
nsTokenAllocator* aTokenAllocator,
nsNodeAllocator* aNodeAllocator):
nsIParserNode() {
mRefCnt = 0;
MOZ_COUNT_CTOR(nsCParserNode);
@ -87,12 +87,10 @@ nsCParserNode::nsCParserNode(CToken* aToken,PRInt32 aLineNumber,nsTokenAllocator
static int theNodeCount=0;
theNodeCount++;
mAttributes=0;
mLineNumber=aLineNumber;
mToken=aToken;
IF_HOLD(mToken);
mTokenAllocator=aTokenAllocator;
mUseCount=0;
mSkippedContent=0;
mGenericState=PR_FALSE;
#ifdef HEAP_ALLOCATED_NODES
mNodeAllocator=aNodeAllocator;
@ -117,7 +115,6 @@ nsCParserNode::~nsCParserNode() {
mNodeAllocator=nsnull;
#endif
mTokenAllocator=0;
mLineNumber=0;
}
@ -129,7 +126,9 @@ nsCParserNode::~nsCParserNode() {
* @return
*/
nsresult nsCParserNode::Init(CToken* aToken,PRInt32 aLineNumber,nsTokenAllocator* aTokenAllocator,nsNodeAllocator* aNodeAllocator) {
nsresult nsCParserNode::Init(CToken* aToken,
nsTokenAllocator* aTokenAllocator,
nsNodeAllocator* aNodeAllocator) {
if(mAttributes && (mAttributes->GetSize())) {
NS_ASSERTION(0!=mTokenAllocator, "Error: Attribute tokens on node without token allocator");
if(mTokenAllocator) {
@ -139,15 +138,11 @@ nsresult nsCParserNode::Init(CToken* aToken,PRInt32 aLineNumber,nsTokenAllocator
}
}
}
mLineNumber=aLineNumber;
mTokenAllocator=aTokenAllocator;
mToken=aToken;
IF_HOLD(mToken);
mGenericState=PR_FALSE;
mUseCount=0;
if(mSkippedContent) {
mSkippedContent->Truncate();
}
#ifdef HEAP_ALLOCATED_NODES
mNodeAllocator=aNodeAllocator;
#endif
@ -201,36 +196,6 @@ const nsAString& nsCParserNode::GetText() const {
return (mToken) ? mToken->GetStringValue() : NS_STATIC_CAST(const nsAString&,GetEmptyString());
}
/**
* Get text value of this node, which translates into
* getting the text value of the underlying token
*
* @update gess 3/25/98
* @param
* @return string ref of text from internal token
*/
const nsString& nsCParserNode::GetSkippedContent() const {
if(mSkippedContent)
return *mSkippedContent;
return GetEmptyString();
}
/**
* Get text value of this node, which translates into
* getting the text value of the underlying token
*
* @update gess 3/25/98
* @param
* @return string ref of text from internal token
*/
void nsCParserNode::SetSkippedContent(nsString& aString) {
if(!mSkippedContent) {
mSkippedContent=new nsString(aString);
}
else *mSkippedContent=aString;
}
/**
* Get node type, meaning, get the tag type of the
* underlying token
@ -328,7 +293,7 @@ PRInt32 nsCParserNode::TranslateToUnicodeStr(nsString& aString) const
* @return int containing the line number the token was found on
*/
PRInt32 nsCParserNode::GetSourceLineNumber(void) const {
return mLineNumber;
return mToken ? mToken->GetLineNumber() : 0;
}
/**
@ -364,7 +329,7 @@ void nsCParserNode::GetSource(nsString& aString) {
for(index=0;index<mAttributes->GetSize();index++) {
CAttributeToken *theToken=(CAttributeToken*)mAttributes->ObjectAt(index);
if(theToken) {
theToken->AppendSource(aString);
theToken->AppendSourceTo(aString);
aString.Append(PRUnichar(' ')); //this will get removed...
}
}
@ -389,10 +354,6 @@ nsresult nsCParserNode::ReleaseAll() {
delete mAttributes;
mAttributes=0;
}
if(mSkippedContent) {
delete mSkippedContent;
mSkippedContent=0;
}
if(mTokenAllocator) {
// It was heap allocated, so free it!

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

@ -100,7 +100,9 @@ class nsCParserNode : public nsIParserNode {
#endif
public:
static nsCParserNode* Create(CToken* aToken,PRInt32 aLineNumber,nsTokenAllocator* aTokenAllocator,nsNodeAllocator* aNodeAllocator)
static nsCParserNode* Create(CToken* aToken,
nsTokenAllocator* aTokenAllocator,
nsNodeAllocator* aNodeAllocator)
{
#ifdef HEAP_ALLOCATED_NODES
return new
@ -109,7 +111,7 @@ class nsCParserNode : public nsIParserNode {
void* place = pool.Alloc(sizeof(nsCParserNode));
return ::new (place)
#endif
nsCParserNode(aToken, aLineNumber, aTokenAllocator, aNodeAllocator);
nsCParserNode(aToken, aTokenAllocator, aNodeAllocator);
}
static void Destroy(nsCParserNode* aNode, nsFixedSizeAllocator& aPool)
@ -132,7 +134,9 @@ class nsCParserNode : public nsIParserNode {
* @update gess5/11/98
* @param aToken is the token this node "refers" to
*/
nsCParserNode(CToken* aToken,PRInt32 aLineNumber,nsTokenAllocator* aTokenAllocator,nsNodeAllocator* aNodeAllocator=0);
nsCParserNode(CToken* aToken,
nsTokenAllocator* aTokenAllocator,
nsNodeAllocator* aNodeAllocator=0);
/**
* Destructor
@ -144,7 +148,9 @@ class nsCParserNode : public nsIParserNode {
* Init
* @update gess5/11/98
*/
virtual nsresult Init(CToken* aToken,PRInt32 aLineNumber,nsTokenAllocator* aTokenAllocator,nsNodeAllocator* aNodeAllocator=0);
virtual nsresult Init(CToken* aToken,
nsTokenAllocator* aTokenAllocator,
nsNodeAllocator* aNodeAllocator=0);
/**
* Retrieve the name of the node
@ -160,20 +166,6 @@ class nsCParserNode : public nsIParserNode {
*/
virtual const nsAString& GetText() const;
/**
* Retrieve skipped context from node
* @update gess5/11/98
* @return string containing skipped content
*/
virtual const nsString& GetSkippedContent() const;
/**
* Retrieve skipped context from node
* @update gess5/11/98
* @return string containing skipped content
*/
virtual void SetSkippedContent(nsString& aString);
/**
* Retrieve the type of the parser node.
* @update gess5/11/98
@ -276,10 +268,8 @@ class nsCParserNode : public nsIParserNode {
*/
virtual nsresult ReleaseAll();
PRInt32 mLineNumber;
CToken* mToken;
nsDeque* mAttributes;
nsString* mSkippedContent;
PRInt32 mUseCount;
PRBool mGenericState;
nsCOMPtr<nsIAtom> mIDAttributeAtom;

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

@ -121,7 +121,6 @@ nsScanner::nsScanner(const nsAString& anHTMLString, const nsString& aCharset, PR
mUnicodeDecoder = 0;
mCharsetSource = kCharsetUninitialized;
SetDocumentCharset(aCharset, aSource);
mNewlinesSkipped=0;
}
/**
@ -150,7 +149,6 @@ nsScanner::nsScanner(nsString& aFilename,PRBool aCreateStream, const nsString& a
mUnicodeDecoder = 0;
mCharsetSource = kCharsetUninitialized;
SetDocumentCharset(aCharset, aSource);
mNewlinesSkipped=0;
}
/**
@ -176,7 +174,6 @@ nsScanner::nsScanner(const nsAString& aFilename,nsInputStream& aStream,const nsS
mUnicodeDecoder = 0;
mCharsetSource = kCharsetUninitialized;
SetDocumentCharset(aCharset, aSource);
mNewlinesSkipped=0;
}
@ -562,55 +559,54 @@ nsresult nsScanner::Peek(nsAString& aStr, PRInt32 aNumChars)
* @param
* @return error status
*/
nsresult nsScanner::SkipWhitespace(void) {
nsresult nsScanner::SkipWhitespace(PRInt32& aNewlinesSkipped) {
if (!mSlidingBuffer) {
return kEOF;
}
nsReadingIterator<PRUnichar> current;
PRBool found;
PRBool skipped = PR_FALSE;
mNewlinesSkipped = 0;
current = mCurrentPosition;
PRUnichar theChar=0;
nsresult result=Peek(theChar);
PRUnichar theChar = 0;
nsresult result = Peek(theChar);
if (result == kEOF) {
return Eof();
}
while (current != mEndPosition) {
nsReadingIterator<PRUnichar> current = mCurrentPosition;
PRBool done = PR_FALSE;
PRBool skipped = PR_FALSE;
while (!done && current != mEndPosition) {
switch(theChar) {
case '\n': mNewlinesSkipped++;
case '\n':
case '\r': aNewlinesSkipped++;
case ' ' :
case '\r':
case '\b':
case '\t':
found=PR_TRUE;
{
skipped = PR_TRUE;
PRUnichar thePrevChar = theChar;
theChar = (++current != mEndPosition) ? *current : '\0';
if ((thePrevChar == '\r' && theChar == '\n') ||
(thePrevChar == '\n' && theChar == '\r')) {
theChar = (++current != mEndPosition) ? *current : '\0'; // CRLF == LFCR => LF
}
}
break;
default:
found=PR_FALSE;
done = PR_TRUE;
break;
}
if(!found) {
break;
}
++current;
theChar = *current;
skipped = PR_TRUE;
}
if (skipped) {
SetPosition(current);
if (current == mEndPosition) {
return Eof();
result = Eof();
}
}
return NS_OK;
return result;
}
/**
@ -1026,95 +1022,102 @@ nsresult nsScanner::ReadNumber(nsReadingIterator<PRUnichar>& aStart,
* @param addTerminal tells us whether to append terminal to aString
* @return error code
*/
nsresult nsScanner::ReadWhitespace(nsString& aString) {
nsresult nsScanner::ReadWhitespace(nsString& aString,
PRInt32& aNewlinesSkipped) {
if (!mSlidingBuffer) {
return kEOF;
}
PRUnichar theChar=0;
nsresult result=Peek(theChar);
PRUnichar theChar = 0;
nsresult result = Peek(theChar);
if (result == kEOF) {
return Eof();
}
nsReadingIterator<PRUnichar> origin, current, end;
PRBool found=PR_FALSE;
PRBool done = PR_FALSE;
origin = mCurrentPosition;
current = origin;
end = mEndPosition;
while(current != end) {
theChar=*current;
if(theChar) {
switch(theChar) {
case ' ':
case '\b':
case '\t':
case kLF:
case kCR:
found=PR_TRUE;
break;
default:
found=PR_FALSE;
break;
}
if(!found) {
while(!done && current != end) {
switch(theChar) {
case '\n':
case '\r': aNewlinesSkipped++;
case ' ' :
case '\b':
case '\t':
{
PRUnichar thePrevChar = theChar;
theChar = (++current != end) ? *current : '\0';
if ((thePrevChar == '\r' && theChar == '\n') ||
(thePrevChar == '\n' && theChar == '\r')) {
theChar = (++current != end) ? *current : '\0'; // CRLF == LFCR => LF
}
}
break;
default:
done = PR_TRUE;
AppendUnicodeTo(origin, current, aString);
break;
}
}
++current;
}
SetPosition(current);
if (current == end) {
AppendUnicodeTo(origin, current, aString);
return Eof();
result = Eof();
}
//DoErrTest(aString);
return result;
}
nsresult nsScanner::ReadWhitespace(nsReadingIterator<PRUnichar>& aStart,
nsReadingIterator<PRUnichar>& aEnd) {
nsReadingIterator<PRUnichar>& aEnd,
PRInt32& aNewlinesSkipped) {
if (!mSlidingBuffer) {
return kEOF;
}
PRUnichar theChar=0;
nsresult result=Peek(theChar);
PRUnichar theChar = 0;
nsresult result = Peek(theChar);
if (result == kEOF) {
return Eof();
}
nsReadingIterator<PRUnichar> origin, current, end;
PRBool found=PR_FALSE;
PRBool done = PR_FALSE;
origin = mCurrentPosition;
current = origin;
end = mEndPosition;
while(current != end) {
theChar=*current;
if(theChar) {
switch(theChar) {
case ' ':
case '\b':
case '\t':
case kLF:
case kCR:
found=PR_TRUE;
break;
default:
found=PR_FALSE;
break;
}
if(!found) {
while(!done && current != end) {
switch(theChar) {
case '\n':
case '\r': aNewlinesSkipped++;
case ' ' :
case '\b':
case '\t':
{
PRUnichar thePrevChar = theChar;
theChar = (++current != end) ? *current : '\0';
if ((thePrevChar == '\r' && theChar == '\n') ||
(thePrevChar == '\n' && theChar == '\r')) {
theChar = (++current != end) ? *current : '\0'; // CRLF == LFCR => LF
}
}
break;
default:
done = PR_TRUE;
aStart = origin;
aEnd = current;
break;
}
++current;
}
}
@ -1122,11 +1125,9 @@ nsresult nsScanner::ReadWhitespace(nsReadingIterator<PRUnichar>& aStart,
if (current == end) {
aStart = origin;
aEnd = current;
return Eof();
result = Eof();
}
//DoErrTest(aString);
return result;
}

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

@ -185,7 +185,7 @@ class nsScanner {
* @update gess 3/25/98
* @return error status
*/
nsresult SkipWhitespace(void);
nsresult SkipWhitespace(PRInt32& aNewlinesSkipped);
/**
* Determine if the scanner has reached EOF.
@ -214,9 +214,11 @@ class nsScanner {
nsresult ReadNumber(nsReadingIterator<PRUnichar>& aStart,
nsReadingIterator<PRUnichar>& aEnd,
PRInt32 aBase);
nsresult ReadWhitespace(nsString& aString);
nsresult ReadWhitespace(nsString& aString,
PRInt32& aNewlinesSkipped);
nsresult ReadWhitespace(nsReadingIterator<PRUnichar>& aStart,
nsReadingIterator<PRUnichar>& aEnd);
nsReadingIterator<PRUnichar>& aEnd,
PRInt32& aNewlinesSkipped);
/**
* Consume characters until you find the terminal char
@ -363,8 +365,6 @@ class nsScanner {
PRBool IsIncremental(void) {return mIncremental;}
void SetIncremental(PRBool anIncrValue) {mIncremental=anIncrValue;}
PRInt32 GetNewlinesSkipped(void) { return mNewlinesSkipped; }
protected:
@ -396,7 +396,6 @@ class nsScanner {
PRInt32 mCharsetSource;
nsString mCharset;
nsIUnicodeDecoder *mUnicodeDecoder;
PRInt32 mNewlinesSkipped;
};
#endif

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

@ -67,6 +67,7 @@ CToken::CToken(PRInt32 aTag) {
#endif
mAttrCount=0;
mNewlineCount=0;
mLineNumber = 0;
mTypeID=aTag;
// Note that the use count starts with 1 instead of 0. This
// is because of the assumption that any token created is in
@ -156,7 +157,7 @@ void CToken::GetSource(nsString& anOutputString){
* @update harishd 3/23/00
* @return reference to string containing string value
*/
void CToken::AppendSource(nsString& anOutputString){
void CToken::AppendSourceTo(nsAString& anOutputString){
anOutputString.Append(GetStringValue());
}
@ -182,16 +183,6 @@ PRInt32 CToken::GetTypeID(void) {
return mTypeID;
}
/**
* Sets the attribute count for this token
*
* @update gess 3/25/98
* @param value -- new attr count
*/
void CToken::SetAttributeCount(PRInt16 value) {
mAttrCount=value;
}
/**
* Retrieves copy of attr count for this token
*

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

@ -380,9 +380,6 @@ CViewSourceHTML::CViewSourceHTML() : mFilename(), mTags(), mErrors() {
*/
CViewSourceHTML::~CViewSourceHTML(){
mParser=0; //just to prove we destructed...
NS_IF_RELEASE(mTokenizer);
}
/**
@ -454,7 +451,9 @@ CViewSourceHTML::CanParse(CParserContext& aParserContext,
* @param aSink
* @return error code (almost always 0)
*/
nsresult CViewSourceHTML::WillBuildModel( const CParserContext& aParserContext,nsIContentSink* aSink){
nsresult CViewSourceHTML::WillBuildModel(const CParserContext& aParserContext,
nsITokenizer* aTokenizer,
nsIContentSink* aSink){
nsresult result=NS_OK;
@ -476,6 +475,7 @@ nsresult CViewSourceHTML::WillBuildModel( const CParserContext& aParserContext,
mMimeType=aParserContext.mMimeType;
mDTDMode=aParserContext.mDTDMode;
mParserCommand=aParserContext.mParserCommand;
mTokenizer = aTokenizer;
mErrorCount=0;
mTagCount=0;
@ -535,12 +535,12 @@ NS_IMETHODIMP CViewSourceHTML::BuildModel(nsIParser* aParser,nsITokenizer* aToke
tag.Assign(NS_LITERAL_STRING("HTML"));
CStartToken htmlToken(tag, eHTMLTag_html);
nsCParserNode htmlNode(&htmlToken,0,0/*stack token*/);
nsCParserNode htmlNode(&htmlToken, 0/*stack token*/);
mSink->OpenHTML(htmlNode);
tag.Assign(NS_LITERAL_STRING("HEAD"));
CStartToken headToken(tag, eHTMLTag_head);
nsCParserNode headNode(&headToken,0,0/*stack token*/);
nsCParserNode headNode(&headToken, 0/*stack token*/);
mSink->OpenHead(headNode);
// Note that XUL with automatically add the prefix "Source of: "
@ -551,7 +551,7 @@ NS_IMETHODIMP CViewSourceHTML::BuildModel(nsIParser* aParser,nsITokenizer* aToke
CStartToken* theToken=NS_STATIC_CAST(CStartToken*,theAllocator->CreateTokenOfType(eToken_start,eHTMLTag_link,tag));
if(theToken) {
CAttributeToken *theAttr;
nsCParserNode theNode(theToken,0,theAllocator);
nsCParserNode theNode(theToken, theAllocator);
theAttr=(CAttributeToken*)theAllocator->CreateTokenOfType(eToken_attribute,eHTMLTag_unknown,NS_LITERAL_STRING("stylesheet"));
theAttr->SetKey(NS_LITERAL_STRING("rel"));
@ -571,7 +571,7 @@ NS_IMETHODIMP CViewSourceHTML::BuildModel(nsIParser* aParser,nsITokenizer* aToke
}
CEndToken endHeadToken(eHTMLTag_head);
nsCParserNode endHeadNode(&endHeadToken,0,0/*stack token*/);
nsCParserNode endHeadNode(&endHeadToken, 0/*stack token*/);
result = mSink->CloseHead(endHeadNode);
if(NS_SUCCEEDED(result)) {
mHasOpenRoot = PR_TRUE;
@ -585,7 +585,7 @@ NS_IMETHODIMP CViewSourceHTML::BuildModel(nsIParser* aParser,nsITokenizer* aToke
tag.Assign(NS_LITERAL_STRING("BODY"));
CStartToken* bodyToken=NS_STATIC_CAST(CStartToken*,theAllocator->CreateTokenOfType(eToken_start, eHTMLTag_body, tag));
if (bodyToken) {
nsCParserNode bodyNode(bodyToken,0,theAllocator);
nsCParserNode bodyNode(bodyToken, theAllocator);
CAttributeToken *theAttr=nsnull;
theAttr=(CAttributeToken*)theAllocator->CreateTokenOfType(eToken_attribute,eHTMLTag_unknown,NS_ConvertASCIItoUCS2(kBodyId));
theAttr->SetKey(NS_LITERAL_STRING("id"));
@ -603,7 +603,7 @@ NS_IMETHODIMP CViewSourceHTML::BuildModel(nsIParser* aParser,nsITokenizer* aToke
if (NS_SUCCEEDED(result)) {
CStartToken theToken(eHTMLTag_pre);
nsCParserNode theNode(&theToken,0,0/*stack token*/);
nsCParserNode theNode(&theToken, 0/*stack token*/);
result=mSink->OpenContainer(theNode);
}
}
@ -664,11 +664,11 @@ nsresult CViewSourceHTML::GenerateSummary() {
*/
void CViewSourceHTML::StartNewPreBlock(void){
CEndToken endToken(eHTMLTag_pre);
nsCParserNode endNode(&endToken,0,0/*stack token*/);
nsCParserNode endNode(&endToken, 0/*stack token*/);
mSink->CloseContainer(endNode);
CStartToken startToken(eHTMLTag_pre);
nsCParserNode startNode(&startToken,0,0/*stack token*/);
nsCParserNode startNode(&startToken, 0/*stack token*/);
mSink->OpenContainer(startNode);
#ifdef DUMP_TO_FILE
@ -712,15 +712,15 @@ NS_IMETHODIMP CViewSourceHTML::DidBuildModel(nsresult anErrorCode,PRBool aNotify
if(ePlainText!=mDocType) {
CEndToken theToken(eHTMLTag_pre);
nsCParserNode preNode(&theToken,0,0/*stack token*/);
nsCParserNode preNode(&theToken, 0/*stack token*/);
mSink->CloseContainer(preNode);
CEndToken bodyToken(eHTMLTag_body);
nsCParserNode bodyNode(&bodyToken,0,0/*stack token*/);
nsCParserNode bodyNode(&bodyToken, 0/*stack token*/);
mSink->CloseBody(bodyNode);
CEndToken htmlToken(eHTMLTag_html);
nsCParserNode htmlNode(&htmlToken,0,0/*stack token*/);
nsCParserNode htmlNode(&htmlToken, 0/*stack token*/);
mSink->CloseHTML(htmlNode);
}
result = mSink->DidBuildModel(1);
@ -754,23 +754,16 @@ NS_IMETHODIMP_(void)
CViewSourceHTML::Terminate() {
}
/**
* Retrieve the preferred tokenizer for use by this DTD.
* @update gess12/28/98
* @param none
* @return ptr to tokenizer
*/
nsresult CViewSourceHTML::GetTokenizer(nsITokenizer*& aTokenizer) {
nsresult result=NS_OK;
if(!mTokenizer) {
result=NS_NewHTMLTokenizer(&mTokenizer,eDTDMode_quirks,mDocType,mParserCommand);
}
aTokenizer=mTokenizer;
return result;
NS_IMETHODIMP_(PRInt32)
CViewSourceHTML::GetType() {
return NS_IPARSER_FLAG_HTML;
}
NS_IMETHODIMP
CViewSourceHTML::CollectSkippedContent(PRInt32 aTag, nsAString& aContent, PRInt32 &aLineNo)
{
return NS_OK;
}
/**
*
@ -946,7 +939,7 @@ nsresult CViewSourceHTML::WriteTag(PRInt32 aTagType,const nsAString & aText,PRIn
nsAutoString beforeText;
beforeText.AssignWithConversion(kBeforeText[aTagType]);
theContext.mITextToken.SetIndirectString(beforeText);
nsCParserNode theNode(&theContext.mITextToken,0,0/*stack token*/);
nsCParserNode theNode(&theContext.mITextToken, 0/*stack token*/);
mSink->AddLeaf(theNode);
}
#ifdef DUMP_TO_FILE
@ -957,7 +950,7 @@ nsresult CViewSourceHTML::WriteTag(PRInt32 aTagType,const nsAString & aText,PRIn
if (mSyntaxHighlight && aTagType != mText) {
CStartToken* theTagToken=NS_STATIC_CAST(CStartToken*,theAllocator->CreateTokenOfType(eToken_start,eHTMLTag_span,NS_LITERAL_STRING("SPAN")));
theContext.mStartNode.Init(theTagToken,mLineNumber,theAllocator);
theContext.mStartNode.Init(theTagToken, theAllocator);
CAttributeToken* theAttr=(CAttributeToken*)theAllocator->CreateTokenOfType(eToken_attribute,eHTMLTag_unknown,NS_ConvertASCIItoUCS2(kElementClasses[aTagType]));
theAttr->SetKey(NS_LITERAL_STRING("class"));
theContext.mStartNode.AddAttribute(theAttr);
@ -975,7 +968,7 @@ nsresult CViewSourceHTML::WriteTag(PRInt32 aTagType,const nsAString & aText,PRIn
theContext.mITextToken.SetIndirectString(aText); //now emit the tag name...
nsCParserNode theNode(&theContext.mITextToken,0,0/*stack token*/);
nsCParserNode theNode(&theContext.mITextToken, 0/*stack token*/);
mSink->AddLeaf(theNode);
#ifdef DUMP_TO_FILE
if (gDumpFile) {
@ -988,7 +981,7 @@ nsresult CViewSourceHTML::WriteTag(PRInt32 aTagType,const nsAString & aText,PRIn
if (mSyntaxHighlight && aTagType != mText) {
theContext.mStartNode.ReleaseAll();
CEndToken theEndToken(eHTMLTag_span);
theContext.mEndNode.Init(&theEndToken,mLineNumber,0/*stack token*/);
theContext.mEndNode.Init(&theEndToken, 0/*stack token*/);
mSink->CloseContainer(theContext.mEndNode); //emit </starttag>...
#ifdef DUMP_TO_FILE
if (gDumpFile)
@ -1004,7 +997,7 @@ nsresult CViewSourceHTML::WriteTag(PRInt32 aTagType,const nsAString & aText,PRIn
nsAutoString afterText;
afterText.AssignWithConversion(kAfterText[aTagType]);
theContext.mITextToken.SetIndirectString(afterText);
nsCParserNode theNode(&theContext.mITextToken,0,0/*stack token*/);
nsCParserNode theNode(&theContext.mITextToken, 0/*stack token*/);
mSink->AddLeaf(theNode);
}
#ifdef DUMP_TO_FILE
@ -1033,7 +1026,7 @@ NS_IMETHODIMP CViewSourceHTML::HandleToken(CToken* aToken,nsIParser* aParser) {
mSink=(nsIHTMLContentSink*)aParser->GetContentSink();
CSharedVSContext& theContext=CSharedVSContext::GetSharedContext();
theContext.mTokenNode.Init(theToken,mLineNumber,mTokenizer->GetTokenAllocator());
theContext.mTokenNode.Init(theToken, mTokenizer->GetTokenAllocator());
eHTMLTags theParent=(mTags.Length()) ? (eHTMLTags)mTags.Last() : eHTMLTag_unknown;
eHTMLTags theChild=(eHTMLTags)aToken->GetTypeID();
@ -1058,8 +1051,9 @@ NS_IMETHODIMP CViewSourceHTML::HandleToken(CToken* aToken,nsIParser* aParser) {
if(theParent==theChild) {
mTags.Truncate(mTags.Length()-1);
}
const nsAString& endValue = aToken->GetStringValue();
result=WriteTag(mEndTag,endValue,0,PR_TRUE);
result=WriteTag(mEndTag,endValue,aToken->GetAttributeCount(),PR_TRUE);
}
break;

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

@ -82,7 +82,7 @@ protected:
nsParser* mParser;
nsIHTMLContentSink* mSink;
PRInt32 mLineNumber;
nsITokenizer* mTokenizer;
nsITokenizer* mTokenizer; // weak
PRInt32 mStartTag;
PRInt32 mEndTag;

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

@ -126,14 +126,14 @@ class CStartToken: public CHTMLToken {
virtual const char* GetClassName(void);
virtual PRInt32 GetTokenType(void);
PRBool IsEmpty(void);
void SetEmpty(PRBool aValue);
virtual PRBool IsEmpty(void);
virtual void SetEmpty(PRBool aValue);
#ifdef DEBUG
virtual void DebugDumpSource(nsOutputStream& out);
#endif
virtual const nsAString& GetStringValue();
virtual void GetSource(nsString& anOutputString);
virtual void AppendSource(nsString& anOutputString);
virtual void AppendSourceTo(nsAString& anOutputString);
//the following info is used to set well-formedness state on start tags...
virtual eContainerInfo GetContainerInfo(void) const {return mContainerInfo;}
@ -185,7 +185,7 @@ class CEndToken: public CHTMLToken {
#endif
virtual const nsAString& GetStringValue();
virtual void GetSource(nsString& anOutputString);
virtual void AppendSource(nsString& anOutputString);
virtual void AppendSourceTo(nsAString& anOutputString);
protected:
nsString mTextValue;
@ -241,7 +241,7 @@ class CEntityToken : public CHTMLToken {
#endif
virtual const nsAString& GetStringValue(void);
virtual void GetSource(nsString& anOutputString);
virtual void AppendSource(nsString& anOutputString);
virtual void AppendSourceTo(nsAString& anOutputString);
protected:
nsString mTextValue;
@ -373,7 +373,7 @@ class CAttributeToken: public CHTMLToken {
#endif
virtual const nsAString& GetStringValue(void);
virtual void GetSource(nsString& anOutputString);
virtual void AppendSource(nsString& anOutputString);
virtual void AppendSourceTo(nsAString& anOutputString);
#ifdef DEBUG
virtual void DebugDumpSource(nsOutputStream& out);
#endif

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

@ -115,7 +115,8 @@ public:
PRInt32 aVersion) = 0;
NS_IMETHOD WillBuildModel(const CParserContext& aParserContext,
nsIContentSink* aSink=0) = 0;
nsITokenizer* aTokenizer,
nsIContentSink* aSink) = 0;
/**
* Called by the parser after the parsing process has concluded
@ -125,7 +126,7 @@ public:
*/
NS_IMETHOD DidBuildModel(nsresult anErrorCode, PRBool aNotifySink,
nsIParser* aParser,
nsIContentSink* aSink = nsnull) = 0;
nsIContentSink* aSink) = 0;
/**
* Called by the parser after the parsing process has concluded
@ -134,8 +135,8 @@ public:
* @return
*/
NS_IMETHOD BuildModel(nsIParser* aParser, nsITokenizer* aTokenizer,
nsITokenObserver* anObserver = nsnull,
nsIContentSink* aSink = nsnull) = 0;
nsITokenObserver* anObserver,
nsIContentSink* aSink) = 0;
/**
* Called during model building phase of parse process. Each token
@ -149,14 +150,6 @@ public:
*/
NS_IMETHOD HandleToken(CToken* aToken,nsIParser* aParser) = 0;
/**
*
* @update gess 12/20/99
* @param ptr-ref to (out) tokenizer
* @return nsresult
*/
NS_IMETHOD GetTokenizer(nsITokenizer*& aTokenizer) = 0;
/**
* If the parse process gets interrupted midway, this method is
* called by the parser prior to resuming the process.
@ -206,6 +199,10 @@ public:
*/
NS_IMETHOD_(void) Terminate() = 0;
NS_IMETHOD_(PRInt32) GetType() = 0;
NS_IMETHOD CollectSkippedContent(PRInt32 aTag, nsAString& aContent, PRInt32 &aLineNo) = 0;
/* XXX Temporary measure, pending further work by RickG */
@ -235,16 +232,17 @@ public:
NS_IMETHOD_(const nsIID&) GetMostDerivedIID(void) const;\
NS_IMETHOD CreateNewInstance(nsIDTD** aInstancePtrResult);\
NS_IMETHOD_(eAutoDetectResult) CanParse(CParserContext& aParserContext, const nsString& aBuffer, PRInt32 aVersion);\
NS_IMETHOD WillBuildModel( const CParserContext& aParserContext,nsIContentSink* aSink=0);\
NS_IMETHOD DidBuildModel(nsresult anErrorCode,PRBool aNotifySink,nsIParser* aParser,nsIContentSink* aSink=0);\
NS_IMETHOD BuildModel(nsIParser* aParser,nsITokenizer* aTokenizer,nsITokenObserver* anObserver=0,nsIContentSink* aSink=0);\
NS_IMETHOD WillBuildModel( const CParserContext& aParserContext, nsITokenizer* aTokenizer, nsIContentSink* aSink);\
NS_IMETHOD DidBuildModel(nsresult anErrorCode,PRBool aNotifySink,nsIParser* aParser,nsIContentSink* aSink);\
NS_IMETHOD BuildModel(nsIParser* aParser,nsITokenizer* aTokenizer,nsITokenObserver* anObserver,nsIContentSink* aSink);\
NS_IMETHOD HandleToken(CToken* aToken,nsIParser* aParser);\
NS_IMETHOD GetTokenizer(nsITokenizer*& aTokenizer);\
NS_IMETHOD WillResumeParse(nsIContentSink* aSink = 0);\
NS_IMETHOD WillInterruptParse(nsIContentSink* aSink = 0);\
NS_IMETHOD_(PRBool) CanContain(PRInt32 aParent,PRInt32 aChild) const;\
NS_IMETHOD_(PRBool) IsContainer(PRInt32 aTag) const;\
NS_IMETHOD CollectSkippedContent(PRInt32 aTag, nsAString& aContent, PRInt32 &aLineNo);\
NS_IMETHOD_(void) Terminate();\
NS_IMETHOD_(PRInt32) GetType(); \
NS_IMETHOD StringTagToIntTag(const nsAString &aTag, PRInt32* aIntTag) const ;\
NS_IMETHOD_(const PRUnichar *) IntTagToStringTag(PRInt32 aIntTag) const ;\
NS_IMETHOD ConvertEntityToUnicode(const nsAString& aEntity, PRInt32* aUnicode) const ;\

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

@ -99,13 +99,6 @@ class nsIParserNode { // XXX Should be nsAParserNode
*/
virtual const nsAString& GetText() const =0; //get plain text if available
/**
* Retrieve skipped context from node
* @update gess5/11/98
* @return string containing skipped content
*/
virtual const nsString& GetSkippedContent() const =0;
/**
* Retrieve the type of the parser node.
* @update gess5/11/98

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

@ -188,7 +188,7 @@ class CToken {
/** @update harishd 03/23/00
* @return reference to string containing string value
*/
virtual void AppendSource(nsString& anOutputString);
virtual void AppendSourceTo(nsAString& anOutputString);
/**
* Sets the ordinal value of this token (not currently used)
@ -204,13 +204,6 @@ class CToken {
*/
virtual PRInt32 GetTypeID(void);
/**
* Sets the # of attributes found for this token.
* @update gess5/11/98
* @param value is the attr count
*/
virtual void SetAttributeCount(PRInt16 aValue);
/**
* Getter which retrieves the current attribute count for this token
* @update gess5/11/98
@ -269,6 +262,34 @@ class CToken {
*/
virtual PRBool IsWellFormed(void) const {return PR_FALSE;}
virtual PRBool IsEmpty(void) { return PR_FALSE; }
/**
* If aValue is TRUE then the token represents a short-hand tag
*/
virtual void SetEmpty(PRBool aValue) { return ; }
PRInt32 GetNewlineCount()
{
return mNewlineCount;
}
void SetNewlineCount(PRInt32 aCount)
{
mNewlineCount = aCount;
}
PRInt32 GetLineNumber()
{
return mLineNumber;
}
void SetLineNumber(PRInt32 aLineNumber)
{
mLineNumber = mLineNumber == 0 ? aLineNumber : mLineNumber;
}
void SetAttributeCount(PRInt16 aValue) { mAttrCount = aValue; }
/**
* perform self test.
@ -278,7 +299,7 @@ class CToken {
static int GetTokenCount();
PRInt32 mNewlineCount;
protected:
/**
@ -288,6 +309,8 @@ protected:
PRInt32 mTypeID;
PRInt32 mUseCount;
PRInt32 mNewlineCount;
PRInt32 mLineNumber;
PRInt16 mAttrCount;
};

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

@ -266,8 +266,6 @@ CNavDTD::~CNavDTD(){
mBodyContext=0;
}
NS_IF_RELEASE(mTokenizer);
if(mTempContext) {
delete mTempContext;
mTempContext=0;
@ -385,7 +383,9 @@ CNavDTD::CanParse(CParserContext& aParserContext,
* @param aSink
* @return error code (almost always 0)
*/
nsresult CNavDTD::WillBuildModel( const CParserContext& aParserContext,nsIContentSink* aSink) {
nsresult CNavDTD::WillBuildModel(const CParserContext& aParserContext,
nsITokenizer* aTokenizer,
nsIContentSink* aSink) {
nsresult result=NS_OK;
mFilename=aParserContext.mScanner->GetFilename();
@ -394,7 +394,7 @@ nsresult CNavDTD::WillBuildModel( const CParserContext& aParserContext,nsIConte
mDTDMode=aParserContext.mDTDMode;
mParserCommand=aParserContext.mParserCommand;
mMimeType=aParserContext.mMimeType;
mTokenizer = aTokenizer;
mBodyContext->SetNodeAllocator(&mNodeAllocator);
if((!aParserContext.mPrevContext) && (aSink)) {
@ -471,97 +471,73 @@ nsresult CNavDTD::WillBuildModel( const CParserContext& aParserContext,nsIConte
nsresult CNavDTD::BuildModel(nsIParser* aParser,nsITokenizer* aTokenizer,nsITokenObserver* anObserver,nsIContentSink* aSink) {
NS_PRECONDITION(mBodyContext!=nsnull,"Create a context before calling build model");
nsresult result=NS_OK;
nsresult result = NS_OK;
if(aTokenizer) {
nsITokenizer* oldTokenizer=mTokenizer;
mTokenizer=aTokenizer;
mParser=(nsParser*)aParser;
if (aTokenizer && mSink && aParser) {
nsITokenizer* oldTokenizer = mTokenizer;
if(mTokenizer) {
mTokenAllocator=mTokenizer->GetTokenAllocator();
mTokenizer = aTokenizer;
mParser = (nsParser*)aParser;
mTokenAllocator = mTokenizer->GetTokenAllocator();
if(NS_FAILED(result)) return result;
if(mSink) {
if(!mBodyContext->GetCount()) {
CStartToken* theToken=nsnull;
if(ePlainText==mDocType) {
//we do this little trick for text files, in both normal and viewsource mode...
theToken=NS_STATIC_CAST(CStartToken*,mTokenAllocator->CreateTokenOfType(eToken_start,eHTMLTag_pre));
if(theToken) {
mTokenizer->PushTokenFront(theToken);
}
}
// always open a body if frames are disabled....
if(!(mFlags & NS_DTD_FLAG_FRAMES_ENABLED)) {
theToken=NS_STATIC_CAST(CStartToken*,mTokenAllocator->CreateTokenOfType(eToken_start,eHTMLTag_body,NS_LITERAL_STRING("body")));
mTokenizer->PushTokenFront(theToken);
}
//if the content model is empty, then begin by opening <html>...
theToken=NS_STATIC_CAST(CStartToken*,mTokenAllocator->CreateTokenOfType(eToken_start,eHTMLTag_html,NS_LITERAL_STRING("html")));
if(theToken) {
mTokenizer->PushTokenFront(theToken); //this token should get pushed on the context stack.
}
if (mBodyContext->GetCount() == 0) {
CStartToken* theToken=nsnull;
if(ePlainText==mDocType) {
//we do this little trick for text files, in both normal and viewsource mode...
theToken=NS_STATIC_CAST(CStartToken*,mTokenAllocator->CreateTokenOfType(eToken_start,eHTMLTag_pre));
if(theToken) {
mTokenizer->PushTokenFront(theToken);
}
mSink->WillProcessTokens();
while(NS_SUCCEEDED(result)){
//Currently nsIHTMLContentSink does nothing with a call to WillProcessAToken.
//mSink->WillProcessAToken();
#if 0
int n=aTokenizer->GetCount();
if(n>50) n=50;
for(int i=0;i<n;i++){
CToken* theToken=aTokenizer->GetTokenAt(i);
printf("\nToken[%i],%p",i,theToken);
}
printf("\n");
#endif
if(!(mFlags & NS_DTD_FLAG_STOP_PARSING)) {
CToken* theToken=mTokenizer->PopToken();
if(theToken) {
result=HandleToken(theToken,aParser);
}
else break;
}
else {
result = NS_ERROR_HTMLPARSER_STOPPARSING;
break;
}
if ((NS_ERROR_HTMLPARSER_INTERRUPTED == mSink->DidProcessAToken())) {
// The content sink has requested that DTD interrupt processing tokens
// So we need to make sure the parser is in a state where it can be
// interrupted.
// The mParser->CanInterrupt will return TRUE if BuildModel was called
// from a place in the parser where it prepared to handle a return value of
// NS_ERROR_HTMLPARSER_INTERRUPTED.
// If the parser has mPrevContext then it may be processing
// Script so we should not allow it to be interrupted.
if ((mParser->CanInterrupt()) &&
(nsnull == mParser->PeekContext()->mPrevContext) &&
(eHTMLTag_unknown==mSkipTarget)) {
result = NS_ERROR_HTMLPARSER_INTERRUPTED;
break;
}
}
}//while
mTokenizer=oldTokenizer;
//Currently nsIHTMLContentSink does nothing with a call to DidProcessATokens().
//mSink->DidProcessTokens();
}
// always open a body if frames are disabled....
if(!(mFlags & NS_DTD_FLAG_FRAMES_ENABLED)) {
theToken=NS_STATIC_CAST(CStartToken*,mTokenAllocator->CreateTokenOfType(eToken_start,eHTMLTag_body,NS_LITERAL_STRING("body")));
mTokenizer->PushTokenFront(theToken);
}
//if the content model is empty, then begin by opening <html>...
theToken=NS_STATIC_CAST(CStartToken*,mTokenAllocator->CreateTokenOfType(eToken_start,eHTMLTag_html,NS_LITERAL_STRING("html")));
if(theToken) {
mTokenizer->PushTokenFront(theToken); //this token should get pushed on the context stack.
}
}
mSink->WillProcessTokens();
while (NS_SUCCEEDED(result)) {
if (!(mFlags & NS_DTD_FLAG_STOP_PARSING)) {
CToken* theToken = mTokenizer->PopToken();
if (theToken) {
result = HandleToken(theToken,aParser);
}
else break;
}
else {
result = NS_ERROR_HTMLPARSER_STOPPARSING;
break;
}
if ((NS_ERROR_HTMLPARSER_INTERRUPTED == mSink->DidProcessAToken())) {
// The content sink has requested that DTD interrupt processing tokens
// So we need to make sure the parser is in a state where it can be
// interrupted.
// The mParser->CanInterrupt will return TRUE if BuildModel was called
// from a place in the parser where it prepared to handle a return value of
// NS_ERROR_HTMLPARSER_INTERRUPTED.
// If the parser has mPrevContext then it may be processing
// Script so we should not allow it to be interrupted.
if ((mParser->CanInterrupt()) &&
(nsnull == mParser->PeekContext()->mPrevContext) &&
(eHTMLTag_unknown==mSkipTarget)) {
result = NS_ERROR_HTMLPARSER_INTERRUPTED;
break;
}
}
}//while
mTokenizer = oldTokenizer;
}
else result=NS_ERROR_HTMLPARSER_BADTOKENIZER;
return result;
}
@ -688,6 +664,13 @@ CNavDTD::Terminate()
mFlags |= NS_DTD_FLAG_STOP_PARSING;
}
NS_IMETHODIMP_(PRInt32)
CNavDTD::GetType()
{
return NS_IPARSER_FLAG_HTML;
}
/**
* --- Backwards compatibility ---
* Use this method to determine if the tag in question needs a BODY.
@ -746,6 +729,10 @@ nsresult CNavDTD::HandleToken(CToken* aToken,nsIParser* aParser){
eHTMLTags theTag=(eHTMLTags)theToken->GetTypeID();
PRBool execSkipContent=PR_FALSE;
aToken->SetLineNumber(mLineNumber);
mLineNumber += aToken->GetNewlineCount();
/* ---------------------------------------------------------------------------------
To understand this little piece of code, you need to look below too.
In essence, this code caches "skipped content" until we find a given skiptarget.
@ -774,7 +761,7 @@ nsresult CNavDTD::HandleToken(CToken* aToken,nsIParser* aParser){
if(theTag != mBodyContext->Last() || theType!=eToken_end) {
// attribute source is a part of start token.
if(theType!=eToken_attribute) {
aToken->AppendSource(mScratch);
aToken->AppendSourceTo(mScratch);
}
IF_FREE(aToken, mTokenAllocator);
return result;
@ -818,7 +805,7 @@ nsresult CNavDTD::HandleToken(CToken* aToken,nsIParser* aParser){
// Fall through if the skipped content collection is |not| in progress - bug 124788
}
else {
mMisplacedContent.Push(theToken);
PushIntoMisplacedStack(theToken);
return result;
}
}
@ -867,7 +854,7 @@ nsresult CNavDTD::HandleToken(CToken* aToken,nsIParser* aParser){
//If you're here then we found a child of the body that was out of place.
//We're going to move it to the body by storing it temporarily on the misplaced stack.
//However, in quirks mode, a few tags request, ambiguosly, for a BODY. - Bugs 18928, 24204.-
mMisplacedContent.Push(aToken);
PushIntoMisplacedStack(aToken);
if(DoesRequireBody(aToken,mTokenizer)) {
CToken* theBodyToken=NS_STATIC_CAST(CToken*,mTokenAllocator->CreateTokenOfType(eToken_start,eHTMLTag_body,NS_LITERAL_STRING("body")));
result=HandleToken(theBodyToken,aParser);
@ -889,6 +876,8 @@ nsresult CNavDTD::HandleToken(CToken* aToken,nsIParser* aParser){
(gHTMLElements[theTag].mSkipTarget) &&
(!theStartToken->IsEmpty())) { // added empty token check for bug 44186
//create a new target
NS_ASSERTION(mSkippedContent.GetSize() == 0, "all the skipped content tokens did not get handled");
mSkippedContent.Empty();
mSkipTarget=gHTMLElements[theTag].mSkipTarget;
mSkippedContent.Push(theToken);
}
@ -969,7 +958,7 @@ nsresult CNavDTD::DidHandleStartTag(nsIParserNode& aNode,eHTMLTags aChildTag){
if(theNextToken) {
eHTMLTokenTypes theType=eHTMLTokenTypes(theNextToken->GetTokenType());
if(eToken_newline==theType){
mLineNumber++;
mLineNumber += theNextToken->GetNewlineCount();
theNextToken=mTokenizer->PopToken(); //skip 1st newline inside PRE and LISTING
IF_FREE(theNextToken, mTokenAllocator); // fix for Bug 29379
}//if
@ -983,10 +972,15 @@ nsresult CNavDTD::DidHandleStartTag(nsIParserNode& aNode,eHTMLTags aChildTag){
{
STOP_TIMER()
MOZ_TIMER_DEBUGLOG(("Stop: Parse Time: CNavDTD::DidHandleStartTag(), this=%p\n", this));
const nsString& theString=aNode.GetSkippedContent();
nsAutoString theString;
PRInt32 lineNo = 0;
result = CollectSkippedContent(aChildTag, theString, lineNo);
NS_ENSURE_SUCCESS(result, result);
if(0<theString.Length()) {
CTextToken *theToken=NS_STATIC_CAST(CTextToken*,mTokenAllocator->CreateTokenOfType(eToken_text,eHTMLTag_text,theString));
nsCParserNode theNode(theToken,0,mTokenAllocator);
nsCParserNode theNode(theToken, mTokenAllocator);
result=mSink->AddLeaf(theNode); //when the node get's destructed, so does the new token
}
MOZ_TIMER_DEBUGLOG(("Start: Parse Time: CNavDTD::DidHandleStartTag(), this=%p\n", this));
@ -1006,7 +1000,7 @@ nsresult CNavDTD::DidHandleStartTag(nsIParserNode& aNode,eHTMLTags aChildTag){
CTextToken theToken(theNumber);
PRInt32 theLineNumber=0;
nsCParserNode theNode(&theToken,theLineNumber,0 /*stack token*/);
nsCParserNode theNode(&theToken, 0 /*stack token*/);
result=mSink->AddLeaf(theNode);
}
break;
@ -1353,12 +1347,7 @@ void WriteTokenToLog(CToken* aToken) {
*/
nsresult CNavDTD::WillHandleStartTag(CToken* aToken,eHTMLTags aTag,nsIParserNode& aNode) {
nsresult result=NS_OK;
PRInt32 theAttrCount = aNode.GetAttributeCount();
//first let's see if there's some skipped content to deal with...
if(gHTMLElements[aTag].mSkipTarget) {
result=CollectSkippedContent(aNode,theAttrCount);
}
PRInt32 theAttrCount = aNode.GetAttributeCount();
//this little gem creates a special attribute for the editor team to use.
//The attribute only get's applied to unknown tags, and is used by ender
@ -1452,7 +1441,7 @@ nsresult CNavDTD::WillHandleStartTag(CToken* aToken,eHTMLTags aTag,nsIParserNode
//because this code calls CloseHead() directly, stack-based token/nodes are ok.
CEndToken theToken(eHTMLTag_head);
nsCParserNode theNode(&theToken,mLineNumber,0 /*stack token*/);
nsCParserNode theNode(&theToken, 0 /*stack token*/);
result=CloseHead(&theNode);
}
}
@ -1470,6 +1459,7 @@ static void PushMisplacedAttributes(nsIParserNode& aNode,nsDeque& aDeque,PRInt32
while(aCount){
theAttrToken=theAttrNode->PopAttributeToken();
if(theAttrToken) {
theAttrToken->SetNewlineCount(0);
aDeque.Push(theAttrToken);
}
aCount--;
@ -1518,7 +1508,7 @@ nsresult CNavDTD::HandleOmittedTag(CToken* aToken,eHTMLTags aChildTag,eHTMLTags
if(mBodyContext->mContextTopIndex>-1) {
mMisplacedContent.Push(aToken);
PushIntoMisplacedStack(aToken);
IF_HOLD(aToken); // Hold on to this token for later use.
@ -1526,8 +1516,14 @@ nsresult CNavDTD::HandleOmittedTag(CToken* aToken,eHTMLTags aChildTag,eHTMLTags
if(attrCount > 0) PushMisplacedAttributes(*aNode,mMisplacedContent,attrCount);
if(gHTMLElements[aChildTag].mSkipTarget) {
mMisplacedContent.Push(mTokenAllocator->CreateTokenOfType(eToken_text,eHTMLTag_text,aNode->GetSkippedContent()));
mMisplacedContent.Push(mTokenAllocator->CreateTokenOfType(eToken_end,aChildTag));
nsAutoString theString;
PRInt32 lineNo = 0;
result = CollectSkippedContent(aChildTag, theString, lineNo);
NS_ENSURE_SUCCESS(result, result);
PushIntoMisplacedStack(mTokenAllocator->CreateTokenOfType(eToken_text,eHTMLTag_text,theString));
PushIntoMisplacedStack(mTokenAllocator->CreateTokenOfType(eToken_end,aChildTag));
}
mFlags |= NS_DTD_FLAG_MISPLACED_CONTENT; // This state would help us in gathering all the misplaced elements
@ -1538,7 +1534,7 @@ nsresult CNavDTD::HandleOmittedTag(CToken* aToken,eHTMLTags aChildTag,eHTMLTags
IF_HOLD(aToken); // Hold on to this token for later use. Ref Bug. 53695
mMisplacedContent.Push(aToken);
PushIntoMisplacedStack(aToken);
// If the token is attributed then save those attributes too.
if(attrCount > 0) PushMisplacedAttributes(*aNode,mMisplacedContent,attrCount);
}
@ -1640,7 +1636,7 @@ nsresult CNavDTD::HandleStartToken(CToken* aToken) {
//Begin by gathering up attributes...
nsCParserNode* theNode=mNodeAllocator.CreateNode(aToken,mLineNumber,mTokenAllocator);
nsCParserNode* theNode=mNodeAllocator.CreateNode(aToken, mTokenAllocator);
eHTMLTags theChildTag=(eHTMLTags)aToken->GetTypeID();
PRInt16 attrCount=aToken->GetAttributeCount();
@ -1679,15 +1675,10 @@ nsresult CNavDTD::HandleStartToken(CToken* aToken) {
}
}
mLineNumber += aToken->mNewlineCount;
PRBool theExclusive=PR_FALSE;
theHeadIsParent=nsHTMLElement::IsChildOfHead(theChildTag,theExclusive);
switch(theChildTag) {
case eHTMLTag_newline:
mLineNumber++;
break;
case eHTMLTag_area:
if(!mOpenMapCount) isTokenHandled=PR_TRUE;
@ -1931,7 +1922,7 @@ nsresult CNavDTD::HandleEndToken(CToken* aToken) {
case eHTMLTag_form:
{
//this is safe because we call close container directly. This node/token is not cached.
nsCParserNode theNode((CHTMLToken*)aToken,mLineNumber,mTokenAllocator);
nsCParserNode theNode((CHTMLToken*)aToken, mTokenAllocator);
result=CloseContainer(&theNode,theChildTag,PR_FALSE);
}
break;
@ -2163,7 +2154,7 @@ nsresult CNavDTD::HandleEntityToken(CToken* aToken) {
eHTMLTags theParentTag=mBodyContext->Last();
nsCParserNode* theNode=mNodeAllocator.CreateNode(aToken,mLineNumber,mTokenAllocator);
nsCParserNode* theNode=mNodeAllocator.CreateNode(aToken, mTokenAllocator);
if(theNode) {
PRBool theParentContains=-1; //set to -1 to force CanOmit to recompute...
if(CanOmit(theParentTag,eHTMLTag_entity,theParentContains)) {
@ -2196,11 +2187,8 @@ nsresult CNavDTD::HandleCommentToken(CToken* aToken) {
nsresult result=NS_OK;
CCommentToken* theToken = NS_STATIC_CAST(CCommentToken*,aToken);
const nsAString& theComment = theToken->GetStringValue();
mLineNumber += CountCharInReadable(theComment, PRUnichar(kNewLine));
nsCParserNode* theNode=mNodeAllocator.CreateNode(aToken, mTokenAllocator);
nsCParserNode* theNode=mNodeAllocator.CreateNode(aToken,mLineNumber,mTokenAllocator);
if(theNode) {
#ifdef RICKG_DEBUG
@ -2234,7 +2222,7 @@ nsresult CNavDTD::HandleCommentToken(CToken* aToken) {
*/
nsresult CNavDTD::HandleAttributeToken(CToken* aToken) {
NS_PRECONDITION(0!=aToken,kNullToken);
NS_ERROR("attribute encountered -- this shouldn't happen!");
NS_ERROR("attribute encountered -- this shouldn't happen unless the attribute was not part of a start tag!");
return NS_OK;
}
@ -2277,7 +2265,7 @@ nsresult CNavDTD::HandleProcessingInstructionToken(CToken* aToken){
nsresult result=NS_OK;
nsCParserNode* theNode=mNodeAllocator.CreateNode(aToken,mLineNumber,mTokenAllocator);
nsCParserNode* theNode=mNodeAllocator.CreateNode(aToken, mTokenAllocator);
if(theNode) {
#ifdef RICKG_DEBUG
@ -2327,7 +2315,7 @@ nsresult CNavDTD::HandleDocTypeDeclToken(CToken* aToken){
docTypeStr.Cut(0,2); // Now remove "<!" from the begining
theToken->SetStringValue(docTypeStr);
nsCParserNode* theNode=mNodeAllocator.CreateNode(aToken,mLineNumber,mTokenAllocator);
nsCParserNode* theNode=mNodeAllocator.CreateNode(aToken, mTokenAllocator);
if(theNode) {
STOP_TIMER();
@ -2394,6 +2382,7 @@ nsresult CNavDTD::CollectAttributes(nsIParserNode& aNode,eHTMLTags aTag,PRInt32
// "SELECTED/", and ">". In this case the "SELECTED/" key will be sanitized to
// a legitimate "SELECTED" key.
((CAttributeToken*)theToken)->SanitizeKey();
mLineNumber += theToken->GetNewlineCount();
#ifdef RICKG_DEBUG
WriteTokenToLog(theToken);
@ -2419,78 +2408,75 @@ nsresult CNavDTD::CollectAttributes(nsIParserNode& aNode,eHTMLTags aTag,PRInt32
* @param holds the number of skipped content elements encountered
* @return Error condition.
*/
nsresult CNavDTD::CollectSkippedContent(nsIParserNode& aNode,PRInt32 &aCount) {
NS_IMETHODIMP
CNavDTD::CollectSkippedContent(PRInt32 aTag, nsAString& aContent, PRInt32 &aLineNo) {
eHTMLTags theNodeTag=(eHTMLTags)aNode.GetNodeType();
NS_ASSERTION(aTag >= eHTMLTag_unknown && aTag <= NS_HTML_TAG_MAX, "tag array out of bounds");
int aIndex=0;
int aMax=mSkippedContent.GetSize();
aContent.Truncate();
NS_ASSERTION(eHTMLTag_unknown != gHTMLElements[aTag].mSkipTarget, "cannot collect content for this tag");
if (eHTMLTag_unknown == gHTMLElements[aTag].mSkipTarget) {
// This tag doesn't support skipped content.
aLineNo = -1;
return NS_OK;
}
aLineNo = mLineNumber;
// XXX rickg This linefeed conversion stuff should be moved out of
// the parser and into the form element code
PRBool aMustConvertLinebreaks = PR_FALSE;
PRBool mustConvertLinebreaks = PR_FALSE;
mScratch.Truncate();
nsCParserNode* theNode=NS_STATIC_CAST(nsCParserNode*,&aNode);
if(theNode) {
theNode->SetSkippedContent(mScratch); //this guarantees us some skipped content storage.
for(aIndex=0;aIndex<aMax;aIndex++){
CHTMLToken* theNextToken=(CHTMLToken*)mSkippedContent.PopFront();
eHTMLTokenTypes theTokenType=(eHTMLTokenTypes)theNextToken->GetTokenType();
PRInt32 i = 0;
PRInt32 tagCount = mSkippedContent.GetSize();
for (i = 0; i< tagCount; i++){
CHTMLToken* theNextToken = (CHTMLToken*)mSkippedContent.PopFront();
if (theNextToken) {
eHTMLTokenTypes theTokenType = (eHTMLTokenTypes)theNextToken->GetTokenType();
// Dont worry about attributes here because it's already stored in
// the start token as mTrailing content and will get appended in
// start token's GetSource();
if(eToken_attribute!=theTokenType) {
if (eToken_attribute!=theTokenType) {
if ((eToken_entity==theTokenType) &&
((eHTMLTag_textarea==theNodeTag) || (eHTMLTag_title==theNodeTag))) {
((eHTMLTag_textarea == aTag) || (eHTMLTag_title == aTag))) {
mScratch.Truncate();
((CEntityToken*)theNextToken)->TranslateToUnicodeStr(mScratch);
// since this is an entity, we know that it's only one character.
// check to see if it's a CR, in which case we'll need to do line
// termination conversion at the end.
if(!mScratch.IsEmpty()){
aMustConvertLinebreaks |= (mScratch[0] == kCR);
theNode->mSkippedContent->Append(mScratch);
if (!mScratch.IsEmpty()){
mustConvertLinebreaks |= (mScratch[0] == kCR);
aContent.Append(mScratch);
}
else {
// We thought it was an entity but it is not! - bug 79492
theNode->mSkippedContent->Append(PRUnichar('&'));
theNode->mSkippedContent->Append(theNextToken->GetStringValue());
aContent.Append(PRUnichar('&'));
aContent.Append(theNextToken->GetStringValue());
}
}
else theNextToken->AppendSource(*theNode->mSkippedContent);
else theNextToken->AppendSourceTo(aContent);
}
IF_FREE(theNextToken, mTokenAllocator);
}
// if the string contained CRs (hence is either CR, or CRLF terminated)
// we need to convert line breaks
if (aMustConvertLinebreaks)
{
/*
PRInt32 offset;
while ((offset = aNode.mSkippedContent.Find("\r\n")) != kNotFound)
aNode.mSkippedContent.Cut(offset, 1); // remove the CR
// now replace remaining CRs with LFs
aNode.mSkippedContent.ReplaceChar("\r", kNewLine);
*/
#if 1
nsLinebreakConverter::ConvertStringLineBreaks(*theNode->mSkippedContent,
nsLinebreakConverter::eLinebreakAny, nsLinebreakConverter::eLinebreakContent);
#endif
}
// Let's hope that this does not hamper the PERFORMANCE!!
mLineNumber += theNode->mSkippedContent->CountChar(kNewLine);
IF_FREE(theNextToken, mTokenAllocator);
}
// if the string contained CRs (hence is either CR, or CRLF terminated)
// we need to convert line breaks
if (mustConvertLinebreaks)
{
InPlaceConvertLineEndings(aContent);
}
// Note: TEXTAREA content is PCDATA and hence the newlines are already accounted for.
mLineNumber += (aTag != eHTMLTag_textarea) ? aContent.CountChar(kNewLine) : 0;
return NS_OK;
}
/***********************************************************************************
The preceeding tables determine the set of elements each tag can contain...
***********************************************************************************/
@ -3004,7 +2990,7 @@ nsresult CNavDTD::CloseTransientStyles(eHTMLTags aChildTag){
for(theTagPos=mBodyContext->mOpenStyles;theTagPos>0;theTagPos--){
eHTMLTags theTag=GetTopNode();
CStartToken token(theTag);
nsCParserNode theNode(&token,mLineNumber,0 /*stack token*/);
nsCParserNode theNode(&token, 0 /*stack token*/);
token.SetTypeID(theTag);
result=CloseContainer(theNode,theTag,PR_FALSE);
}
@ -3849,7 +3835,12 @@ nsresult CNavDTD::AddHeadLeaf(nsIParserNode *aNode){
if(NS_OK==result) {
if(eHTMLTag_title==theTag) {
const nsString& theString=aNode->GetSkippedContent();
nsAutoString theString;
PRInt32 lineNo = 0;
result = CollectSkippedContent(eHTMLTag_title, theString, lineNo);
NS_ENSURE_SUCCESS(result, result);
PRInt32 theLen=theString.Length();
CBufDescriptor theBD(theString.get(), PR_TRUE, theLen+1, theLen);
nsAutoString theString2(theBD);
@ -3937,22 +3928,6 @@ nsresult CNavDTD::CreateContextStackFor(eHTMLTags aChildTag){
return result;
}
/**
* Retrieve the preferred tokenizer for use by this DTD.
* @update gess12/28/98
* @param none
* @return ptr to tokenizer
*/
NS_IMETHODIMP
CNavDTD::GetTokenizer(nsITokenizer*& aTokenizer) {
nsresult result=NS_OK;
if(!mTokenizer) {
result=NS_NewHTMLTokenizer(&mTokenizer,mDTDMode,mDocType,mParserCommand);
}
aTokenizer=mTokenizer;
return result;
}
/**
*
* @update gess5/18/98

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

@ -330,6 +330,15 @@ public:
nsresult DoFragment(PRBool aFlag);
nsresult PushIntoMisplacedStack(CToken* aToken)
{
NS_ENSURE_ARG_POINTER(aToken);
aToken->SetNewlineCount(0); // Note: We have already counted the newlines for these tokens
mMisplacedContent.Push(aToken);
return NS_OK;
}
protected:
nsresult CollectAttributes(nsIParserNode& aNode,eHTMLTags aTag,PRInt32 aCount);
@ -348,7 +357,7 @@ protected:
nsDTDContext* mBodyContext;
nsDTDContext* mTempContext;
nsParser* mParser;
nsITokenizer* mTokenizer;
nsITokenizer* mTokenizer; // weak
nsString mFilename;
nsString mScratch; //used for various purposes; non-persistent

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

@ -210,8 +210,7 @@ COtherDTD::~COtherDTD(){
delete mNodeAllocator;
mNodeAllocator=nsnull;
}
NS_IF_RELEASE(mTokenizer);
NS_IF_RELEASE(mSink);
}
@ -324,7 +323,9 @@ COtherDTD::CanParse(CParserContext& aParserContext, const nsString& aBuffer,
* @param aSink
* @return error code (almost always 0)
*/
nsresult COtherDTD::WillBuildModel( const CParserContext& aParserContext,nsIContentSink* aSink){
nsresult COtherDTD::WillBuildModel(const CParserContext& aParserContext,
nsITokenizer* aTokenizer,
nsIContentSink* aSink){
nsresult result=NS_OK;
mFilename=aParserContext.mScanner->GetFilename();
@ -334,6 +335,7 @@ nsresult COtherDTD::WillBuildModel( const CParserContext& aParserContext,nsICon
mHasOpenScript=PR_FALSE;
mDTDMode=aParserContext.mDTDMode;
mParserCommand=aParserContext.mParserCommand;
mTokenizer = aTokenizer;
if((!aParserContext.mPrevContext) && (aSink)) {
@ -488,6 +490,18 @@ COtherDTD::Terminate()
mDTDState = NS_ERROR_HTMLPARSER_STOPPARSING;
}
NS_IMETHODIMP_(PRInt32)
COtherDTD::GetType()
{
return NS_IPARSER_FLAG_HTML;
}
NS_IMETHODIMP
COtherDTD::CollectSkippedContent(PRInt32 aTag, nsAString& aContent, PRInt32 &aLineNo)
{
return NS_OK;
}
/**
* This big dispatch method is used to route token handler calls to the right place.
* What's wrong with it? This table, and the dispatch methods themselves need to be
@ -682,7 +696,7 @@ nsresult COtherDTD::HandleStartToken(CToken* aToken) {
//Begin by gathering up attributes...
nsresult result=NS_OK;
nsCParserNode* theNode=mNodeAllocator->CreateNode(aToken,mLineNumber,mTokenAllocator);
nsCParserNode* theNode=mNodeAllocator->CreateNode(aToken, mTokenAllocator);
if(theNode) {
eHTMLTags theChildTag=(eHTMLTags)aToken->GetTypeID();
@ -695,7 +709,7 @@ nsresult COtherDTD::HandleStartToken(CToken* aToken) {
result=WillHandleStartTag(aToken,theChildTag,*theNode);
if(NS_OK==result) {
mLineNumber += aToken->mNewlineCount;
mLineNumber += aToken->GetNewlineCount();
PRBool theTagWasHandled=PR_FALSE;
@ -769,7 +783,7 @@ nsresult COtherDTD::HandleEndToken(CToken* aToken) {
}
CElement* theElement=gElementTable->mElements[theParent];
if(theElement) {
nsCParserNode* theNode=mNodeAllocator->CreateNode(aToken,mLineNumber,mTokenAllocator);
nsCParserNode* theNode=mNodeAllocator->CreateNode(aToken, mTokenAllocator);
if(theNode) {
result=theElement->HandleEndToken(theNode,theChildTag,mBodyContext,mSink);
IF_FREE(theNode, mNodeAllocator);
@ -864,7 +878,7 @@ nsresult COtherDTD::HandleEntityToken(CToken* aToken) {
eHTMLTags theParent=mBodyContext->Last();
CElement* theElement=gElementTable->mElements[theParent];
if(theElement) {
nsCParserNode theNode(aToken,mLineNumber,0);
nsCParserNode theNode(aToken, 0);
result=theElement->HandleStartToken(&theNode,eHTMLTag_text,mBodyContext,mSink);
}
}
@ -980,23 +994,6 @@ PRBool COtherDTD::IsInlineElement(PRInt32 aChildID,PRInt32 aParentID) const {
PRBool COtherDTD::IsContainer(PRInt32 aTag) const {
return gElementTable->mElements[eHTMLTags(aTag)]->IsContainer();
}
/**
* Retrieve the preferred tokenizer for use by this DTD.
* @update gess12/28/98
* @param none
* @return ptr to tokenizer
*/
nsresult COtherDTD::GetTokenizer(nsITokenizer*& aTokenizer) {
nsresult result=NS_OK;
if(!mTokenizer) {
result=NS_NewHTMLTokenizer(&mTokenizer,mDTDMode,mDocType,mParserCommand);
}
aTokenizer=mTokenizer;
return result;
}
/**
*

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

@ -175,7 +175,7 @@ protected:
nsString mFilename;
PRInt32 mLineNumber;
nsParser* mParser;
nsITokenizer* mTokenizer;
nsITokenizer* mTokenizer; // weak
nsTokenAllocator* mTokenAllocator;
nsNodeAllocator* mNodeAllocator;
PRBool mHasOpenScript;

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

@ -263,18 +263,17 @@ public:
}
nsresult AutoGenerateStructure(eHTMLTags *aTagList,nsDTDContext* aContext,nsIHTMLContentSink* aSink) {
PRInt32 theLineNumber=0;
nsresult result=NS_OK;
CStartToken theToken(*aTagList);
nsCParserNode theNode(&theToken,theLineNumber,0 /*stack token*/);
nsCParserNode theNode(&theToken, 0 /*stack token*/);
result=OpenContainer(&theNode,*aTagList,aContext,aSink);
if(eHTMLTag_unknown!=*(aTagList+1)) {
AutoGenerateStructure(++aTagList,aContext,aSink);
}
CEndToken theEndToken(*aTagList--);
nsCParserNode theEndNode(&theEndToken,theLineNumber,0 /*stack token*/);
nsCParserNode theEndNode(&theEndToken, 0 /*stack token*/);
result=CloseContainer(&theEndNode,*aTagList,aContext,aSink);
return result;
@ -825,7 +824,7 @@ public:
if(aContext->mTableStates) {
if(aContext->mTableStates->CanOpenTBody()) {
CToken* theToken=(CStartToken*)aContext->mTokenAllocator->CreateTokenOfType(eToken_start,eHTMLTag_tbody);
nsCParserNode* theNode=aContext->mNodeAllocator->CreateNode(theToken,0,0);
nsCParserNode* theNode=aContext->mNodeAllocator->CreateNode(theToken, 0);
result=HandleStartToken(theNode,eHTMLTag_tbody,aContext,aSink);
}
@ -1023,8 +1022,7 @@ public:
aContext->IncrementCounter(theGrandParentTag,*theNode,theNumber);
CTextToken theToken(theNumber);
PRInt32 theLineNumber=0;
nsCParserNode theNewNode(&theToken,theLineNumber,0 /*stack token*/);
nsCParserNode theNewNode(&theToken, 0 /*stack token*/);
*theNode = theNewNode;
#endif
result=aSink->AddLeaf(*theNode);
@ -1227,13 +1225,12 @@ public:
if(aNode) {
#if 0
CStartToken theToken(aTag);
PRInt32 theLineNumber=0;
nsCParserNode theNode(&theToken,theLineNumber);
nsCParserNode theNode(&theToken);
theNode.SetSkippedContent(mText);
result=aSink->AddLeaf(theNode);
#endif
nsCParserNode *theNode=(nsCParserNode*)aNode;
theNode->SetSkippedContent(mText);
//theNode->SetSkippedContent(mText); XXX why do we need this?
result=aSink->AddLeaf(*theNode);
}
mText.Truncate(0);
@ -1816,7 +1813,7 @@ public:
//let's auto open the body
CToken* theToken=(CStartToken*)aContext->mTokenAllocator->CreateTokenOfType(eToken_start,eHTMLTag_body);
nsCParserNode* theNode=aContext->mNodeAllocator->CreateNode(theToken,0,0);
nsCParserNode* theNode=aContext->mNodeAllocator->CreateNode(theToken, 0);
result=theBody->HandleStartToken(theNode,eHTMLTag_body,aContext,aSink);

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

@ -40,6 +40,8 @@
#include "CParserContext.h"
#include "nsToken.h"
#include "prenv.h"
#include "nsHTMLTokenizer.h"
#include "nsExpatDriver.h"
MOZ_DECL_CTOR_COUNTER(CParserContext)
@ -70,7 +72,8 @@ CParserContext::CParserContext(nsScanner* aScanner,
mAutoDetectStatus=aStatus;
mTransferBuffer=0;
mDTD=aDTD;
NS_IF_ADDREF(mDTD);
NS_IF_ADDREF(mDTD);
mTokenizer = 0;
mTransferBufferSize=eTransferBufferSize;
mStreamListenerState=eNone;
mMultipart=PR_TRUE;
@ -103,6 +106,9 @@ CParserContext::CParserContext(const CParserContext &aContext) : mMimeType() {
mDTD=aContext.mDTD;
NS_IF_ADDREF(mDTD);
mTokenizer = aContext.mTokenizer;
NS_IF_ADDREF(mTokenizer);
mTransferBufferSize=eTransferBufferSize;
mStreamListenerState=aContext.mStreamListenerState;
mMultipart=aContext.mMultipart;
@ -132,6 +138,7 @@ CParserContext::~CParserContext(){
NS_IF_RELEASE(mDTD);
NS_IF_RELEASE(mListener);
NS_IF_RELEASE(mTokenizer);
//Remember that it's ok to simply ingore the PrevContext.
@ -149,11 +156,28 @@ void CParserContext::SetMimeType(const nsACString& aMimeType){
if(mMimeType.Equals(NS_LITERAL_CSTRING(kHTMLTextContentType)))
mDocType=eHTML_Strict;
else if (mMimeType.Equals(NS_LITERAL_CSTRING(kXMLTextContentType)) ||
mMimeType.Equals(NS_LITERAL_CSTRING(kXMLApplicationContentType)) ||
else if (mMimeType.Equals(NS_LITERAL_CSTRING(kXMLTextContentType)) ||
mMimeType.Equals(NS_LITERAL_CSTRING(kXMLApplicationContentType)) ||
mMimeType.Equals(NS_LITERAL_CSTRING(kXHTMLApplicationContentType)) ||
mMimeType.Equals(NS_LITERAL_CSTRING(kXULTextContentType)) ||
mMimeType.Equals(NS_LITERAL_CSTRING(kRDFTextContentType)) ||
mMimeType.Equals(NS_LITERAL_CSTRING(kXIFTextContentType)))
mMimeType.Equals(NS_LITERAL_CSTRING(kXULTextContentType)) ||
mMimeType.Equals(NS_LITERAL_CSTRING(kRDFTextContentType)))
mDocType=eXML;
}
nsresult
CParserContext::GetTokenizer(PRInt32 aType, nsITokenizer*& aTokenizer) {
nsresult result = NS_OK;
if(!mTokenizer) {
if (aType == NS_IPARSER_FLAG_HTML || mParserCommand == eViewSource) {
result = NS_NewHTMLTokenizer(&mTokenizer,mDTDMode,mDocType,mParserCommand);
}
else if (aType == NS_IPARSER_FLAG_XML)
{
result = CallQueryInterface(mDTD, &mTokenizer);
}
}
aTokenizer = mTokenizer;
return result;
}

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

@ -77,6 +77,7 @@ public:
CParserContext( const CParserContext& aContext);
~CParserContext();
nsresult GetTokenizer(PRInt32 aType, nsITokenizer*& aTokenizer);
void SetMimeType(const nsACString& aMimeType);
nsCOMPtr<nsIRequest> mRequest; // provided by necko to differnciate different input streams
@ -85,6 +86,7 @@ public:
nsIRequestObserver* mListener;
char* mTransferBuffer;
void* mKey;
nsITokenizer* mTokenizer;
CParserContext* mPrevContext;
nsScanner* mScanner;

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

@ -1383,7 +1383,8 @@ nsNodeAllocator::~nsNodeAllocator() {
#endif
}
nsCParserNode* nsNodeAllocator::CreateNode(CToken* aToken,PRInt32 aLineNumber,nsTokenAllocator* aTokenAllocator) {
nsCParserNode* nsNodeAllocator::CreateNode(CToken* aToken,
nsTokenAllocator* aTokenAllocator) {
nsCParserNode* result=0;
#ifdef HEAP_ALLOCATED_NODES
@ -1395,10 +1396,10 @@ nsCParserNode* nsNodeAllocator::CreateNode(CToken* aToken,PRInt32 aLineNumber,ns
result=NS_STATIC_CAST(nsCParserNode*,mSharedNodes.Pop());
if(result) {
result->Init(aToken,aLineNumber,aTokenAllocator,this);
result->Init(aToken, aTokenAllocator,this);
}
else{
result=nsCParserNode::Create(aToken,aLineNumber,aTokenAllocator,this);
result=nsCParserNode::Create(aToken, aTokenAllocator,this);
#ifdef DEBUG_TRACK_NODES
mCount++;
AddNode(NS_STATIC_CAST(nsCParserNode*,result));
@ -1406,7 +1407,7 @@ nsCParserNode* nsNodeAllocator::CreateNode(CToken* aToken,PRInt32 aLineNumber,ns
IF_HOLD(result);
}
#else
result=nsCParserNode::Create(aToken,aLineNumber,aTokenAllocator,this);
result=nsCParserNode::Create(aToken, aTokenAllocator,this);
IF_HOLD(result);
#endif
return result;

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

@ -303,7 +303,7 @@ public:
nsNodeAllocator();
virtual ~nsNodeAllocator();
virtual nsCParserNode* CreateNode(CToken* aToken=nsnull,PRInt32 aLineNumber=1,nsTokenAllocator* aTokenAllocator=0);
virtual nsCParserNode* CreateNode(CToken* aToken=nsnull, nsTokenAllocator* aTokenAllocator=0);
nsFixedSizeAllocator& GetArenaPool() { return mNodePool; }
@ -646,6 +646,80 @@ inline PRBool HasOptionalEndTag(eHTMLTags aTag) {
return FindTagInSet(aTag,gHasOptionalEndTags,sizeof(gHasOptionalEndTags)/sizeof(eHTMLTag_body));
}
static void
InPlaceConvertLineEndings( nsAString& aString )
{
// go from '\r\n' or '\r' to '\n'
nsAString::iterator iter;
aString.BeginWriting(iter);
PRUnichar* S = iter.get();
size_t N = iter.size_forward();
// this fragment must be the entire string because
// (a) no multi-fragment string is writable, so only an illegal cast could give us one, and
// (b) else we would have to do more work (watching for |to| to fall off the end)
NS_ASSERTION(aString.Length() == N, "You cheated... multi-fragment strings are never writable!");
// we scan/convert in two phases (but only one pass over the string)
// until we have to skip a character, we only need to touch end-of-line chars
// after that, we'll have to start moving every character we want to keep
// use array indexing instead of pointers, because compilers optimize that better
// this first loop just converts line endings... no characters get moved
size_t i = 0;
PRBool just_saw_cr = PR_FALSE;
for ( ; i < N; ++i )
{
// if it's something we need to convert...
if ( S[i] == '\r' )
{
S[i] = '\n';
just_saw_cr = PR_TRUE;
}
else
{
// else, if it's something we need to skip...
// i.e., a '\n' immediately following a '\r',
// then we need to start moving any character we want to keep
// and we have a second loop for that, so get out of this one
if ( S[i] == '\n' && just_saw_cr )
break;
just_saw_cr = PR_FALSE;
}
}
// this second loop handles the rest of the buffer, moving characters down
// _and_ converting line-endings as it goes
// start the loop at |from = i| so that that |just_saw_cr| gets cleared automatically
size_t to = i;
for ( size_t from = i; from < N; ++from )
{
// if it's something we need to convert...
if ( S[from] == '\r' )
{
S[to++] = '\n';
just_saw_cr = PR_TRUE;
}
else
{
// else, if it's something we need to copy...
// i.e., NOT a '\n' immediately following a '\r'
if ( S[from] != '\n' || !just_saw_cr )
S[to++] = S[from];
just_saw_cr = PR_FALSE;
}
}
// if we chopped characters out of the string, we need to shorten it logically
if ( to < N )
aString.SetLength(to);
}
#endif

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

@ -822,7 +822,8 @@ nsExpatDriver::CanParse(CParserContext& aParserContext,
}
NS_IMETHODIMP
nsExpatDriver::WillBuildModel(const CParserContext& aParserContext,
nsExpatDriver::WillBuildModel(const CParserContext& aParserContext,
nsITokenizer* aTokenizer,
nsIContentSink* aSink)
{
@ -882,12 +883,6 @@ nsExpatDriver::DidBuildModel(nsresult anErrorCode,
return result;
}
NS_IMETHODIMP nsExpatDriver::GetTokenizer(nsITokenizer*& aTokenizer)
{
aTokenizer = this;
return NS_OK;
}
NS_IMETHODIMP
nsExpatDriver::WillTokenize(PRBool aIsFinalChunk,
nsTokenAllocator* aTokenAllocator)
@ -926,8 +921,20 @@ nsExpatDriver::Terminate()
mInternalState = NS_ERROR_HTMLPARSER_STOPPARSING;
}
NS_IMETHODIMP_(PRInt32)
nsExpatDriver::GetType()
{
return NS_IPARSER_FLAG_XML;
}
/*************************** Unused methods ***************************************/
NS_IMETHODIMP
nsExpatDriver::CollectSkippedContent(PRInt32 aTag, nsAString& aContent, PRInt32 &aLineNo)
{
return NS_OK;
}
NS_IMETHODIMP_(CToken*)
nsExpatDriver::PushTokenFront(CToken* aToken)
{

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

@ -607,7 +607,9 @@ nsresult nsHTMLTokenizer::ConsumeTag(PRUnichar aChar,CToken*& aToken,nsScanner&
* @param aLeadingWS: contains ws chars that preceeded the first attribute
* @return
*/
nsresult nsHTMLTokenizer::ConsumeAttributes(PRUnichar aChar,CStartToken* aToken,nsScanner& aScanner) {
nsresult nsHTMLTokenizer::ConsumeAttributes(PRUnichar aChar,
CToken* aToken,
nsScanner& aScanner) {
PRBool done=PR_FALSE;
nsresult result=NS_OK;
PRInt16 theAttrCount=0;
@ -649,20 +651,24 @@ nsresult nsHTMLTokenizer::ConsumeAttributes(PRUnichar aChar,CStartToken* aToken,
}
}//if
#ifdef DEBUG
if(NS_SUCCEEDED(result)){
result=aScanner.SkipWhitespace();
if(NS_SUCCEEDED(result)) {
result=aScanner.Peek(aChar);
if(NS_SUCCEEDED(result)) {
if(aChar==kGreaterThan) { //you just ate the '>'
aScanner.GetChar(aChar); //skip the '>'
done=PR_TRUE;
}
else if(aChar==kLessThan) {
done=PR_TRUE;
}
}//if
}
PRInt32 newline = 0;
result = aScanner.SkipWhitespace(newline);
NS_ASSERTION(newline == 0, "CAttribute::Consume() failed to collect all the newlines!");
}
#endif
if (NS_SUCCEEDED(result)) {
result = aScanner.Peek(aChar);
if (NS_SUCCEEDED(result)) {
if (aChar == kGreaterThan) { //you just ate the '>'
aScanner.GetChar(aChar); //skip the '>'
done = PR_TRUE;
}
else if(aChar == kLessThan) {
done = PR_TRUE;
}
}//if
}//if
}//while
@ -706,51 +712,28 @@ nsresult nsHTMLTokenizer::ConsumeStartTag(PRUnichar aChar,CToken*& aToken,nsScan
if(NS_SUCCEEDED(result)) {
AddToken(aToken,result,&mTokenDeque,theAllocator);
NS_ENSURE_SUCCESS(result, result);
eHTMLTags theTag=(eHTMLTags)aToken->GetTypeID();
//Good. Now, let's see if the next char is ">".
//If so, we have a complete tag, otherwise, we have attributes.
PRBool theTagHasAttributes=PR_FALSE;
nsReadingIterator<PRUnichar> start, end;
if(NS_OK==result) {
if (mFlags & NS_IPARSER_FLAG_VIEW_SOURCE) {
result = aScanner.ReadWhitespace(start, end);
}
else {
result = aScanner.SkipWhitespace();
}
aToken->mNewlineCount += aScanner.GetNewlinesSkipped();
if(NS_OK==result) {
result=aScanner.Peek(aChar);
if(NS_OK==result) {
if(kGreaterThan!=aChar) { //look for '>'
//push that char back, since we apparently have attributes...
theTagHasAttributes=PR_TRUE;
} //if
else {
aScanner.GetChar(aChar);
}
} //if
}//if
}
CStartToken* theStartToken=NS_STATIC_CAST(CStartToken*,aToken);
if(theTagHasAttributes) {
if (mFlags & NS_IPARSER_FLAG_VIEW_SOURCE) {
// Since we conserve whitespace in view-source mode,
// go back to the beginning of the whitespace section
// and let the first attribute grab it.
aScanner.SetPosition(start, PR_FALSE, PR_TRUE);
}
result=ConsumeAttributes(aChar,theStartToken,aScanner);
}
//Good. Now, let's see if the next char is ">".
//If so, we have a complete tag, otherwise, we have attributes.
result = aScanner.Peek(aChar);
NS_ENSURE_SUCCESS(result, result);
if(kGreaterThan != aChar) { //look for '>'
result = ConsumeAttributes(aChar, aToken, aScanner);
} //if
else {
aScanner.GetChar(aChar);
}
/* Now that that's over with, we have one more problem to solve.
In the case that we just read a <SCRIPT> or <STYLE> tags, we should go and
consume all the content itself.
*/
if(NS_SUCCEEDED(result)) {
CStartToken* theStartToken = NS_STATIC_CAST(CStartToken*,aToken);
//XXX - Find a better soution to record content
//Added _plaintext to fix bug 46054.
if((theTag == eHTMLTag_textarea ||
@ -825,7 +808,19 @@ nsresult nsHTMLTokenizer::ConsumeEndTag(PRUnichar aChar,CToken*& aToken,nsScanne
if(aToken) {
result= aToken->Consume(aChar,aScanner,mFlags); //tell new token to finish consuming text...
AddToken(aToken,result,&mTokenDeque,theAllocator);
NS_ENSURE_SUCCESS(result, result);
result = aScanner.Peek(aChar);
NS_ENSURE_SUCCESS(result, result);
if(kGreaterThan != aChar) {
result = ConsumeAttributes(aChar, aToken, aScanner);
NS_ENSURE_SUCCESS(result, result);
}
else {
aScanner.GetChar(aChar);
}
if(NS_SUCCEEDED(result)) {
eHTMLTags theTag=(eHTMLTags)aToken->GetTypeID();
if((theTag == eHTMLTag_textarea ||

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

@ -84,7 +84,7 @@ protected:
virtual nsresult ConsumeTag(PRUnichar aChar,CToken*& aToken,nsScanner& aScanner,PRBool& aFlushTokens);
virtual nsresult ConsumeStartTag(PRUnichar aChar,CToken*& aToken,nsScanner& aScanner,PRBool& aFlushTokens);
virtual nsresult ConsumeEndTag(PRUnichar aChar,CToken*& aToken,nsScanner& aScanner);
virtual nsresult ConsumeAttributes(PRUnichar aChar,CStartToken* aToken,nsScanner& aScanner);
virtual nsresult ConsumeAttributes(PRUnichar aChar, CToken* aToken, nsScanner& aScanner);
virtual nsresult ConsumeEntity(PRUnichar aChar,CToken*& aToken,nsScanner& aScanner);
virtual nsresult ConsumeWhitespace(PRUnichar aChar,CToken*& aToken,nsScanner& aScanner);
virtual nsresult ConsumeComment(PRUnichar aChar,CToken*& aToken,nsScanner& aScanner);

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

@ -227,6 +227,10 @@ nsresult CStartToken::Consume(PRUnichar aChar, nsScanner& aScanner,PRInt32 aFlag
mTypeID = nsHTMLTags::LookupTag(mTextValue);
}
if (NS_SUCCEEDED(result) && !(aFlag & NS_IPARSER_FLAG_VIEW_SOURCE)) {
result = aScanner.SkipWhitespace(mNewlineCount);
}
return result;
}
@ -286,7 +290,7 @@ void CStartToken::GetSource(nsString& anOutputString){
* @param result appended to the output string.
* @return nada
*/
void CStartToken::AppendSource(nsString& anOutputString){
void CStartToken::AppendSourceTo(nsAString& anOutputString){
anOutputString.Append(PRUnichar('<'));
/*
* Watch out for Bug 15204
@ -329,46 +333,30 @@ CEndToken::CEndToken(const nsAString& aName,eHTMLTags aTag) : CHTMLToken(aTag) {
* @param aFlag - contains information such as |dtd mode|view mode|doctype|etc...
* @return error result
*/
nsresult CEndToken::Consume(PRUnichar aChar, nsScanner& aScanner,PRInt32 aFlag) {
//if you're here, we've already Consumed the <! chars, and are
//ready to Consume the rest of the open tag identifier.
//Stop consuming as soon as you see a space or a '>'.
//NOTE: We don't Consume the tag attributes here, nor do we eat the ">"
nsresult result=NS_OK;
nsAutoString buffer;
PRInt32 offset;
nsresult CEndToken::Consume(PRUnichar aChar, nsScanner& aScanner,PRInt32 aFlag)
{
nsresult result = NS_OK;
if (aFlag & NS_IPARSER_FLAG_HTML) {
nsAutoString theSubstr;
result=aScanner.ReadUntil(theSubstr,kGreaterThan,PR_FALSE);
if (NS_FAILED(result)) {
return result;
}
result=aScanner.GetIdentifier(theSubstr,PR_TRUE);
NS_ENSURE_SUCCESS(result, result);
offset = theSubstr.FindCharInSet(" \r\n\t\b",0);
if (offset != kNotFound) {
theSubstr.Left(buffer, offset);
mTypeID = nsHTMLTags::LookupTag(buffer);
}
else {
mTypeID = nsHTMLTags::LookupTag(theSubstr);
}
mTypeID = (PRInt32)nsHTMLTags::LookupTag(theSubstr);
if(eHTMLTag_userdefined==mTypeID) {
mTextValue=theSubstr;
}
}
else {
mTextValue.SetLength(0);
result=aScanner.ReadUntil(mTextValue,kGreaterThan,PR_FALSE);
if (NS_FAILED(result)) {
return result;
}
mTypeID = eHTMLTag_userdefined;
result = aScanner.ReadIdentifier(mTextValue,PR_TRUE);
NS_ENSURE_SUCCESS(result, result);
mTypeID = nsHTMLTags::LookupTag(mTextValue);
}
result=aScanner.GetChar(aChar); //eat the closing '>;
if (!(aFlag & NS_IPARSER_FLAG_VIEW_SOURCE)) {
result = aScanner.SkipWhitespace(mNewlineCount);
NS_ENSURE_SUCCESS(result, result);
}
return result;
}
@ -466,7 +454,7 @@ void CEndToken::GetSource(nsString& anOutputString){
* @param result appended to the output string.
* @return nada
*/
void CEndToken::AppendSource(nsString& anOutputString){
void CEndToken::AppendSourceTo(nsAString& anOutputString){
anOutputString.Append(NS_LITERAL_STRING("</"));
if(mTextValue.Length()>0)
anOutputString.Append(mTextValue);
@ -1267,6 +1255,8 @@ nsresult CCommentToken::Consume(PRUnichar aChar, nsScanner& aScanner,PRInt32 aFl
else {
result=ConsumeComment(aScanner,mTextValue);
}
mNewlineCount = !(aFlag & NS_IPARSER_FLAG_VIEW_SOURCE) ? mTextValue.CountChar(kNewLine) : -1;
return result;
}
@ -1394,7 +1384,9 @@ nsresult CNewlineToken::Consume(PRUnichar aChar, nsScanner& aScanner,PRInt32 aFl
default:
break;
}
}
}
mNewlineCount = 1;
return result;
}
@ -1531,7 +1523,7 @@ const nsAString& CAttributeToken::GetStringValue(void)
*/
void CAttributeToken::GetSource(nsString& anOutputString){
anOutputString.Truncate();
AppendSource(anOutputString);
AppendSourceTo(anOutputString);
}
/*
@ -1541,7 +1533,7 @@ void CAttributeToken::GetSource(nsString& anOutputString){
* @param result appended to the output string.
* @return nada
*/
void CAttributeToken::AppendSource(nsString& anOutputString){
void CAttributeToken::AppendSourceTo(nsAString& anOutputString){
anOutputString.Append(mTextKey);
if(mTextValue.Length() || mHasEqualWithoutValue)
anOutputString.Append(NS_LITERAL_STRING("="));
@ -1727,10 +1719,10 @@ nsresult CAttributeToken::Consume(PRUnichar aChar, nsScanner& aScanner,PRInt32 a
nsReadingIterator<PRUnichar> wsstart, wsend;
if (aFlag & NS_IPARSER_FLAG_VIEW_SOURCE) {
result = aScanner.ReadWhitespace(wsstart, wsend);
result = aScanner.ReadWhitespace(wsstart, wsend, mNewlineCount);
}
else {
result = aScanner.SkipWhitespace();
result = aScanner.SkipWhitespace(mNewlineCount);
}
if (NS_OK==result) {
@ -1752,11 +1744,11 @@ nsresult CAttributeToken::Consume(PRUnichar aChar, nsScanner& aScanner,PRInt32 a
//now it's time to Consume the (optional) value...
if (NS_OK==result) {
if (aFlag & NS_IPARSER_FLAG_VIEW_SOURCE) {
result = aScanner.ReadWhitespace(start, wsend);
result = aScanner.ReadWhitespace(start, wsend, mNewlineCount);
aScanner.BindSubstring(mTextKey, wsstart, wsend);
}
else {
result = aScanner.SkipWhitespace();
result = aScanner.SkipWhitespace(mNewlineCount);
}
if (NS_OK==result) {
@ -1766,10 +1758,10 @@ nsresult CAttributeToken::Consume(PRUnichar aChar, nsScanner& aScanner,PRInt32 a
result=aScanner.GetChar(aChar); //skip the equal sign...
if (NS_OK==result) {
if (aFlag & NS_IPARSER_FLAG_VIEW_SOURCE) {
result = aScanner.ReadWhitespace(mTextValue);
result = aScanner.ReadWhitespace(mTextValue, mNewlineCount);
}
else {
result = aScanner.SkipWhitespace();
result = aScanner.SkipWhitespace(mNewlineCount);
}
if (NS_OK==result) {
@ -1805,10 +1797,10 @@ nsresult CAttributeToken::Consume(PRUnichar aChar, nsScanner& aScanner,PRInt32 a
}//if
if (NS_OK==result) {
if (aFlag & NS_IPARSER_FLAG_VIEW_SOURCE) {
result = aScanner.ReadWhitespace(mTextValue);
result = aScanner.ReadWhitespace(mTextValue, mNewlineCount);
}
else {
result = aScanner.SkipWhitespace();
result = aScanner.SkipWhitespace(mNewlineCount);
}
}
}//if
@ -1926,7 +1918,7 @@ PRInt32 CWhitespaceToken::GetTokenType(void) {
*/
nsresult CWhitespaceToken::Consume(PRUnichar aChar, nsScanner& aScanner,PRInt32 aFlag) {
mTextValue.Assign(aChar);
nsresult result=aScanner.ReadWhitespace(mTextValue);
nsresult result=aScanner.ReadWhitespace(mTextValue, mNewlineCount);
if(NS_OK==result) {
mTextValue.StripChar(kCR);
}
@ -2237,7 +2229,7 @@ void CEntityToken::GetSource(nsString& anOutputString){
* @param result appended to the output string.
* @return nada
*/
void CEntityToken::AppendSource(nsString& anOutputString){
void CEntityToken::AppendSourceTo(nsAString& anOutputString){
anOutputString.Append(NS_LITERAL_STRING("&"));
anOutputString+=mTextValue;
//anOutputString+=";";

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

@ -41,6 +41,7 @@
#include "nsReadableUtils.h"
#include "prprf.h"
static NS_DEFINE_IID(kIContentSinkIID, NS_ICONTENT_SINK_IID);
static NS_DEFINE_IID(kIHTMLContentSinkIID, NS_IHTML_CONTENT_SINK_IID);
static NS_DEFINE_IID(kILoggingSinkIID, NS_ILOGGING_SINK_IID);
@ -197,6 +198,12 @@ nsLoggingSink::SetParser(nsIParser* aParser) {
theResult=mSink->SetParser(aParser);
}
NS_IF_RELEASE(mParser);
mParser = aParser;
NS_IF_ADDREF(mParser);
return theResult;
}
@ -610,8 +617,16 @@ nsLoggingSink::WriteAttributes(const nsIParserNode& aNode) {
}
if (0 != strchr(gSkippedContentTags, aNode.GetNodeType())) {
nsCOMPtr<nsIDTD> dtd;
mParser->GetDTD(getter_AddRefs(dtd));
NS_ENSURE_TRUE(dtd, NS_ERROR_FAILURE);
nsString theString;
PRInt32 lineNo = 0;
dtd->CollectSkippedContent(aNode.GetNodeType(), theString, lineNo);
char* content;
GetNewCString(aNode.GetSkippedContent(), &content);
GetNewCString(theString, &content);
if(content) {
PR_fprintf(mOutput, " <content value=\"");
PR_fprintf(mOutput, "%s\"/>\n", content) ;
@ -630,7 +645,14 @@ nsLoggingSink::WillWriteAttributes(const nsIParserNode& aNode)
return PR_TRUE;
}
if (0 != strchr(gSkippedContentTags, aNode.GetNodeType())) {
const nsString& content = aNode.GetSkippedContent();
nsCOMPtr<nsIDTD> dtd;
mParser->GetDTD(getter_AddRefs(dtd));
NS_ENSURE_TRUE(dtd, NS_ERROR_FAILURE);
nsString content;
PRInt32 lineNo = 0;
dtd->CollectSkippedContent(aNode.GetNodeType(), content, lineNo);
if (content.Length() > 0) {
return PR_TRUE;
}

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

@ -40,6 +40,7 @@
#define NS_LOGGING_SINK_H__
#include "nsILoggingSink.h"
#include "nsIParser.h"
class nsLoggingSink : public nsILoggingSink {
public:
@ -114,6 +115,7 @@ protected:
int mLevel;
nsIHTMLContentSink *mSink;
PRBool mAutoDeleteOutput;
nsIParser* mParser;
};
#endif

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

@ -1222,7 +1222,9 @@ nsresult nsParser::WillBuildModel(nsString& aFilename){
}
if(PR_TRUE==FindSuitableDTD(*mParserContext,theBuffer)) {
mParserContext->mDTD->WillBuildModel( *mParserContext,mSink);
nsITokenizer* tokenizer;
mParserContext->GetTokenizer(mParserContext->mDTD->GetType(), tokenizer);
mParserContext->mDTD->WillBuildModel(*mParserContext, tokenizer, mSink);
}//if
}//if
}
@ -1548,10 +1550,10 @@ nsresult nsParser::Parse(const nsAString& aSourceBuffer, void* aKey,
return result;
}
nsParser* me = this;
// Maintain a reference to ourselves so we don't go away
// till we're completely done.
NS_ADDREF(me);
nsCOMPtr<nsIParser> kungFuDeathGrip(this);
if(aSourceBuffer.Length() || mUnusedInput.Length()) {
@ -1567,57 +1569,55 @@ nsresult nsParser::Parse(const nsAString& aSourceBuffer, void* aKey,
if((!mParserContext) || (mParserContext->mKey!=aKey)) {
//only make a new context if we dont have one, OR if we do, but has a different context key...
nsScanner* theScanner=new nsScanner(mUnusedInput,mCharset,mCharsetSource);
nsIDTD *theDTD=0;
eAutoDetectResult theStatus=eUnknownDetect;
nsScanner* theScanner = new nsScanner(mUnusedInput,mCharset,mCharsetSource);
NS_ENSURE_TRUE(theScanner, NS_ERROR_OUT_OF_MEMORY);
nsIDTD *theDTD = 0;
eAutoDetectResult theStatus = eUnknownDetect;
if (mParserContext && mParserContext->mMimeType==aMimeType) {
NS_ASSERTION(mParserContext->mDTD,"How come the DTD is null?"); // Ref. Bug 90379
if (mParserContext->mDTD) {
mParserContext->mDTD->CreateNewInstance(&theDTD); // To fix 32263
if (mParserContext) {
// To fix bug 32263 we used create a new instance of the DTD!.
// All we need is a new tokenizer which now gets created with
// a parser context.
theDTD = mParserContext->mDTD;
theStatus=mParserContext->mAutoDetectStatus;
//added this to fix bug 32022.
}
}
pc=new CParserContext(theScanner,aKey, mCommand,0,theDTD,theStatus,aLastCall);
pc = new CParserContext(theScanner, aKey, mCommand, 0, theDTD, theStatus, aLastCall);
NS_ENSURE_TRUE(pc, NS_ERROR_OUT_OF_MEMORY);
if(pc && theScanner) {
PushContext(*pc);
pc->mMultipart=!aLastCall; //by default
if (pc->mPrevContext) {
pc->mMultipart |= pc->mPrevContext->mMultipart; //if available
}
// start fix bug 40143
if(pc->mMultipart) {
pc->mStreamListenerState=eOnDataAvail;
if(pc->mScanner) pc->mScanner->SetIncremental(PR_TRUE);
}
else {
pc->mStreamListenerState=eOnStop;
if(pc->mScanner) pc->mScanner->SetIncremental(PR_FALSE);
}
// end fix for 40143
pc->mContextType=CParserContext::eCTString;
pc->SetMimeType(aMimeType);
pc->mDTDMode=aMode;
mUnusedInput.Truncate(0);
//printf("Parse(string) iterate: %i",PR_FALSE);
pc->mScanner->Append(aSourceBuffer);
// Do not interrupt document.write() - bug 95487
result = ResumeParse(PR_FALSE, PR_FALSE, PR_FALSE);
PushContext(*pc);
pc->mMultipart=!aLastCall; //by default
if (pc->mPrevContext) {
pc->mMultipart |= pc->mPrevContext->mMultipart; //if available
}
else {
NS_RELEASE(me);
return NS_ERROR_OUT_OF_MEMORY;
}
NS_IF_RELEASE(theDTD);
// start fix bug 40143
if(pc->mMultipart) {
pc->mStreamListenerState=eOnDataAvail;
if(pc->mScanner) pc->mScanner->SetIncremental(PR_TRUE);
}
else {
pc->mStreamListenerState=eOnStop;
if(pc->mScanner) pc->mScanner->SetIncremental(PR_FALSE);
}
// end fix for 40143
pc->mContextType=CParserContext::eCTString;
pc->SetMimeType(aMimeType);
pc->mDTDMode=aMode;
mUnusedInput.Truncate(0);
//printf("Parse(string) iterate: %i",PR_FALSE);
pc->mScanner->Append(aSourceBuffer);
// Do not interrupt document.write() - bug 95487
result = ResumeParse(PR_FALSE, PR_FALSE, PR_FALSE);
}
else {
mParserContext->mScanner->Append(aSourceBuffer);
@ -1631,7 +1631,7 @@ nsresult nsParser::Parse(const nsAString& aSourceBuffer, void* aKey,
}
}
}//if
NS_RELEASE(me);
return result;
}
@ -1841,33 +1841,33 @@ nsresult nsParser::ResumeParse(PRBool allowIteration, PRBool aIsFinalChunk, PRBo
* @return error code -- 0 if ok, non-zero if error.
*/
nsresult nsParser::BuildModel() {
//nsDequeIterator e=mParserContext->mTokenDeque.End();
CParserContext* theRootContext = mParserContext;
nsITokenizer* theTokenizer = 0;
// if(!mParserContext->mCurrentPos)
// mParserContext->mCurrentPos=new nsDequeIterator(mParserContext->mTokenDeque.Begin());
nsresult result = NS_OK;
if (mParserContext) {
PRInt32 type = mParserContext->mDTD ? mParserContext->mDTD->GetType() : NS_IPARSER_FLAG_HTML;
mParserContext->GetTokenizer(type, theTokenizer);
}
if (theTokenizer) {
//Get the root DTD for use in model building...
CParserContext* theRootContext=mParserContext;
nsITokenizer* theTokenizer=0;
nsresult result = (mParserContext->mDTD)? mParserContext->mDTD->GetTokenizer(theTokenizer):NS_OK;
if(theTokenizer){
while(theRootContext->mPrevContext) {
theRootContext=theRootContext->mPrevContext;
while (theRootContext->mPrevContext) {
theRootContext = theRootContext->mPrevContext;
}
nsIDTD* theRootDTD=theRootContext->mDTD;
if(theRootDTD) {
nsIDTD* theRootDTD = theRootContext->mDTD;
if (theRootDTD) {
MOZ_TIMER_START(mDTDTime);
result=theRootDTD->BuildModel(this,theTokenizer,mTokenObserver,mSink);
result = theRootDTD->BuildModel(this, theTokenizer, mTokenObserver, mSink);
MOZ_TIMER_STOP(mDTDTime);
}
}
else{
mInternalState=result=NS_ERROR_HTMLPARSER_BADTOKENIZER;
mInternalState = result = NS_ERROR_HTMLPARSER_BADTOKENIZER;
}
return result;
}
@ -1879,12 +1879,14 @@ nsresult nsParser::BuildModel() {
* @param
* @return
*/
nsITokenizer* nsParser::GetTokenizer(void) {
nsITokenizer* theTokenizer=0;
if(mParserContext && mParserContext->mDTD) {
mParserContext->mDTD->GetTokenizer(theTokenizer);
nsresult nsParser::GetTokenizer(nsITokenizer*& aTokenizer) {
nsresult result = NS_OK;
aTokenizer = nsnull;
if(mParserContext) {
PRInt32 type = mParserContext->mDTD ? mParserContext->mDTD->GetType() : NS_IPARSER_FLAG_HTML;
result = mParserContext->GetTokenizer(type, aTokenizer);
}
return theTokenizer;
return result;
}
/*******************************************************************
@ -2446,7 +2448,12 @@ nsresult nsParser::OnStopRequest(nsIRequest *request, nsISupports* aContext,
*/
PRBool nsParser::WillTokenize(PRBool aIsFinalChunk){
nsITokenizer* theTokenizer=0;
nsresult result = (mParserContext->mDTD)? mParserContext->mDTD->GetTokenizer(theTokenizer):NS_OK;
nsresult result = NS_OK;
if (mParserContext) {
PRInt32 type = mParserContext->mDTD ? mParserContext->mDTD->GetType() : NS_IPARSER_FLAG_HTML;
mParserContext->GetTokenizer(type, theTokenizer);
}
if (theTokenizer) {
result = theTokenizer->WillTokenize(aIsFinalChunk,&mTokenAllocator);
}
@ -2466,16 +2473,23 @@ nsresult nsParser::Tokenize(PRBool aIsFinalChunk){
nsITokenizer* theTokenizer = 0;
nsresult result =
(mParserContext && mParserContext->mDTD)? mParserContext->mDTD->GetTokenizer(theTokenizer) : NS_OK;
nsresult result = NS_OK;
if (theTokenizer){
if (mParserContext) {
PRInt32 type = mParserContext->mDTD ? mParserContext->mDTD->GetType() : NS_IPARSER_FLAG_HTML;
mParserContext->GetTokenizer(type, theTokenizer);
}
if (theTokenizer) {
if (mFlags & NS_PARSER_FLAG_FLUSH_TOKENS) {
// For some reason tokens didn't get flushed ( probably
// the parser got blocked before all the tokens in the
// stack got handled ). Flush 'em now. Ref. bug 104856
if (theTokenizer->GetCount() == 0) {
mFlags &= ~NS_PARSER_FLAG_FLUSH_TOKENS; // reset since the tokens have been flushed.
// Resume tokenization for the rest of the document
// since all the tokens in the tokenizer got flushed.
result = Tokenize(aIsFinalChunk);
}
}
else {
@ -2534,7 +2548,11 @@ PRBool nsParser::DidTokenize(PRBool aIsFinalChunk){
PRBool result=PR_TRUE;
nsITokenizer* theTokenizer=0;
nsresult rv = (mParserContext->mDTD)? mParserContext->mDTD->GetTokenizer(theTokenizer):NS_OK;
nsresult rv = NS_OK;
if (mParserContext) {
PRInt32 type = mParserContext->mDTD ? mParserContext->mDTD->GetType() : NS_IPARSER_FLAG_HTML;
mParserContext->GetTokenizer(type, theTokenizer);
}
if (NS_SUCCEEDED(rv) && theTokenizer) {
result = theTokenizer->DidTokenize(aIsFinalChunk);
@ -2556,7 +2574,9 @@ void nsParser::DebugDumpSource(nsOutputStream& aStream) {
PRInt32 theIndex=-1;
nsITokenizer* theTokenizer=0;
if(NS_SUCCEEDED(mParserContext->mDTD->GetTokenizer(theTokenizer))){
PRInt32 type = mParserContext && mParserContext->mDTD ?
mParserContext->mDTD->GetType() : NS_IPARSER_FLAG_HTML;
if(NS_SUCCEEDED(mParserContext->GetTokenizer(type, theTokenizer))){
CToken* theToken;
while(nsnull != (theToken=theTokenizer->GetTokenAt(++theIndex))) {
// theToken->DebugDumpToken(out);

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

@ -297,7 +297,7 @@ class nsParser : public nsIParser,
* @param
* @return
*/
virtual nsITokenizer* GetTokenizer(void);
nsresult GetTokenizer(nsITokenizer*& aTokenizer);
/**
* Get the channel associated with this parser

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

@ -58,10 +58,8 @@ const nsString& GetEmptyString() {
* Default Constructor
*/
nsCParserNode::nsCParserNode()
: mLineNumber(1),
mToken(nsnull),
: mToken(nsnull),
mAttributes(nsnull),
mSkippedContent(nsnull),
mUseCount(0),
mGenericState(PR_FALSE),
mTokenAllocator(nsnull)
@ -79,7 +77,9 @@ nsCParserNode::nsCParserNode()
* @param aToken -- token to init internal token
* @return
*/
nsCParserNode::nsCParserNode(CToken* aToken,PRInt32 aLineNumber,nsTokenAllocator* aTokenAllocator,nsNodeAllocator* aNodeAllocator):
nsCParserNode::nsCParserNode(CToken* aToken,
nsTokenAllocator* aTokenAllocator,
nsNodeAllocator* aNodeAllocator):
nsIParserNode() {
mRefCnt = 0;
MOZ_COUNT_CTOR(nsCParserNode);
@ -87,12 +87,10 @@ nsCParserNode::nsCParserNode(CToken* aToken,PRInt32 aLineNumber,nsTokenAllocator
static int theNodeCount=0;
theNodeCount++;
mAttributes=0;
mLineNumber=aLineNumber;
mToken=aToken;
IF_HOLD(mToken);
mTokenAllocator=aTokenAllocator;
mUseCount=0;
mSkippedContent=0;
mGenericState=PR_FALSE;
#ifdef HEAP_ALLOCATED_NODES
mNodeAllocator=aNodeAllocator;
@ -117,7 +115,6 @@ nsCParserNode::~nsCParserNode() {
mNodeAllocator=nsnull;
#endif
mTokenAllocator=0;
mLineNumber=0;
}
@ -129,7 +126,9 @@ nsCParserNode::~nsCParserNode() {
* @return
*/
nsresult nsCParserNode::Init(CToken* aToken,PRInt32 aLineNumber,nsTokenAllocator* aTokenAllocator,nsNodeAllocator* aNodeAllocator) {
nsresult nsCParserNode::Init(CToken* aToken,
nsTokenAllocator* aTokenAllocator,
nsNodeAllocator* aNodeAllocator) {
if(mAttributes && (mAttributes->GetSize())) {
NS_ASSERTION(0!=mTokenAllocator, "Error: Attribute tokens on node without token allocator");
if(mTokenAllocator) {
@ -139,15 +138,11 @@ nsresult nsCParserNode::Init(CToken* aToken,PRInt32 aLineNumber,nsTokenAllocator
}
}
}
mLineNumber=aLineNumber;
mTokenAllocator=aTokenAllocator;
mToken=aToken;
IF_HOLD(mToken);
mGenericState=PR_FALSE;
mUseCount=0;
if(mSkippedContent) {
mSkippedContent->Truncate();
}
#ifdef HEAP_ALLOCATED_NODES
mNodeAllocator=aNodeAllocator;
#endif
@ -201,36 +196,6 @@ const nsAString& nsCParserNode::GetText() const {
return (mToken) ? mToken->GetStringValue() : NS_STATIC_CAST(const nsAString&,GetEmptyString());
}
/**
* Get text value of this node, which translates into
* getting the text value of the underlying token
*
* @update gess 3/25/98
* @param
* @return string ref of text from internal token
*/
const nsString& nsCParserNode::GetSkippedContent() const {
if(mSkippedContent)
return *mSkippedContent;
return GetEmptyString();
}
/**
* Get text value of this node, which translates into
* getting the text value of the underlying token
*
* @update gess 3/25/98
* @param
* @return string ref of text from internal token
*/
void nsCParserNode::SetSkippedContent(nsString& aString) {
if(!mSkippedContent) {
mSkippedContent=new nsString(aString);
}
else *mSkippedContent=aString;
}
/**
* Get node type, meaning, get the tag type of the
* underlying token
@ -328,7 +293,7 @@ PRInt32 nsCParserNode::TranslateToUnicodeStr(nsString& aString) const
* @return int containing the line number the token was found on
*/
PRInt32 nsCParserNode::GetSourceLineNumber(void) const {
return mLineNumber;
return mToken ? mToken->GetLineNumber() : 0;
}
/**
@ -364,7 +329,7 @@ void nsCParserNode::GetSource(nsString& aString) {
for(index=0;index<mAttributes->GetSize();index++) {
CAttributeToken *theToken=(CAttributeToken*)mAttributes->ObjectAt(index);
if(theToken) {
theToken->AppendSource(aString);
theToken->AppendSourceTo(aString);
aString.Append(PRUnichar(' ')); //this will get removed...
}
}
@ -389,10 +354,6 @@ nsresult nsCParserNode::ReleaseAll() {
delete mAttributes;
mAttributes=0;
}
if(mSkippedContent) {
delete mSkippedContent;
mSkippedContent=0;
}
if(mTokenAllocator) {
// It was heap allocated, so free it!

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

@ -100,7 +100,9 @@ class nsCParserNode : public nsIParserNode {
#endif
public:
static nsCParserNode* Create(CToken* aToken,PRInt32 aLineNumber,nsTokenAllocator* aTokenAllocator,nsNodeAllocator* aNodeAllocator)
static nsCParserNode* Create(CToken* aToken,
nsTokenAllocator* aTokenAllocator,
nsNodeAllocator* aNodeAllocator)
{
#ifdef HEAP_ALLOCATED_NODES
return new
@ -109,7 +111,7 @@ class nsCParserNode : public nsIParserNode {
void* place = pool.Alloc(sizeof(nsCParserNode));
return ::new (place)
#endif
nsCParserNode(aToken, aLineNumber, aTokenAllocator, aNodeAllocator);
nsCParserNode(aToken, aTokenAllocator, aNodeAllocator);
}
static void Destroy(nsCParserNode* aNode, nsFixedSizeAllocator& aPool)
@ -132,7 +134,9 @@ class nsCParserNode : public nsIParserNode {
* @update gess5/11/98
* @param aToken is the token this node "refers" to
*/
nsCParserNode(CToken* aToken,PRInt32 aLineNumber,nsTokenAllocator* aTokenAllocator,nsNodeAllocator* aNodeAllocator=0);
nsCParserNode(CToken* aToken,
nsTokenAllocator* aTokenAllocator,
nsNodeAllocator* aNodeAllocator=0);
/**
* Destructor
@ -144,7 +148,9 @@ class nsCParserNode : public nsIParserNode {
* Init
* @update gess5/11/98
*/
virtual nsresult Init(CToken* aToken,PRInt32 aLineNumber,nsTokenAllocator* aTokenAllocator,nsNodeAllocator* aNodeAllocator=0);
virtual nsresult Init(CToken* aToken,
nsTokenAllocator* aTokenAllocator,
nsNodeAllocator* aNodeAllocator=0);
/**
* Retrieve the name of the node
@ -160,20 +166,6 @@ class nsCParserNode : public nsIParserNode {
*/
virtual const nsAString& GetText() const;
/**
* Retrieve skipped context from node
* @update gess5/11/98
* @return string containing skipped content
*/
virtual const nsString& GetSkippedContent() const;
/**
* Retrieve skipped context from node
* @update gess5/11/98
* @return string containing skipped content
*/
virtual void SetSkippedContent(nsString& aString);
/**
* Retrieve the type of the parser node.
* @update gess5/11/98
@ -276,10 +268,8 @@ class nsCParserNode : public nsIParserNode {
*/
virtual nsresult ReleaseAll();
PRInt32 mLineNumber;
CToken* mToken;
nsDeque* mAttributes;
nsString* mSkippedContent;
PRInt32 mUseCount;
PRBool mGenericState;
nsCOMPtr<nsIAtom> mIDAttributeAtom;

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

@ -121,7 +121,6 @@ nsScanner::nsScanner(const nsAString& anHTMLString, const nsString& aCharset, PR
mUnicodeDecoder = 0;
mCharsetSource = kCharsetUninitialized;
SetDocumentCharset(aCharset, aSource);
mNewlinesSkipped=0;
}
/**
@ -150,7 +149,6 @@ nsScanner::nsScanner(nsString& aFilename,PRBool aCreateStream, const nsString& a
mUnicodeDecoder = 0;
mCharsetSource = kCharsetUninitialized;
SetDocumentCharset(aCharset, aSource);
mNewlinesSkipped=0;
}
/**
@ -176,7 +174,6 @@ nsScanner::nsScanner(const nsAString& aFilename,nsInputStream& aStream,const nsS
mUnicodeDecoder = 0;
mCharsetSource = kCharsetUninitialized;
SetDocumentCharset(aCharset, aSource);
mNewlinesSkipped=0;
}
@ -562,55 +559,54 @@ nsresult nsScanner::Peek(nsAString& aStr, PRInt32 aNumChars)
* @param
* @return error status
*/
nsresult nsScanner::SkipWhitespace(void) {
nsresult nsScanner::SkipWhitespace(PRInt32& aNewlinesSkipped) {
if (!mSlidingBuffer) {
return kEOF;
}
nsReadingIterator<PRUnichar> current;
PRBool found;
PRBool skipped = PR_FALSE;
mNewlinesSkipped = 0;
current = mCurrentPosition;
PRUnichar theChar=0;
nsresult result=Peek(theChar);
PRUnichar theChar = 0;
nsresult result = Peek(theChar);
if (result == kEOF) {
return Eof();
}
while (current != mEndPosition) {
nsReadingIterator<PRUnichar> current = mCurrentPosition;
PRBool done = PR_FALSE;
PRBool skipped = PR_FALSE;
while (!done && current != mEndPosition) {
switch(theChar) {
case '\n': mNewlinesSkipped++;
case '\n':
case '\r': aNewlinesSkipped++;
case ' ' :
case '\r':
case '\b':
case '\t':
found=PR_TRUE;
{
skipped = PR_TRUE;
PRUnichar thePrevChar = theChar;
theChar = (++current != mEndPosition) ? *current : '\0';
if ((thePrevChar == '\r' && theChar == '\n') ||
(thePrevChar == '\n' && theChar == '\r')) {
theChar = (++current != mEndPosition) ? *current : '\0'; // CRLF == LFCR => LF
}
}
break;
default:
found=PR_FALSE;
done = PR_TRUE;
break;
}
if(!found) {
break;
}
++current;
theChar = *current;
skipped = PR_TRUE;
}
if (skipped) {
SetPosition(current);
if (current == mEndPosition) {
return Eof();
result = Eof();
}
}
return NS_OK;
return result;
}
/**
@ -1026,95 +1022,102 @@ nsresult nsScanner::ReadNumber(nsReadingIterator<PRUnichar>& aStart,
* @param addTerminal tells us whether to append terminal to aString
* @return error code
*/
nsresult nsScanner::ReadWhitespace(nsString& aString) {
nsresult nsScanner::ReadWhitespace(nsString& aString,
PRInt32& aNewlinesSkipped) {
if (!mSlidingBuffer) {
return kEOF;
}
PRUnichar theChar=0;
nsresult result=Peek(theChar);
PRUnichar theChar = 0;
nsresult result = Peek(theChar);
if (result == kEOF) {
return Eof();
}
nsReadingIterator<PRUnichar> origin, current, end;
PRBool found=PR_FALSE;
PRBool done = PR_FALSE;
origin = mCurrentPosition;
current = origin;
end = mEndPosition;
while(current != end) {
theChar=*current;
if(theChar) {
switch(theChar) {
case ' ':
case '\b':
case '\t':
case kLF:
case kCR:
found=PR_TRUE;
break;
default:
found=PR_FALSE;
break;
}
if(!found) {
while(!done && current != end) {
switch(theChar) {
case '\n':
case '\r': aNewlinesSkipped++;
case ' ' :
case '\b':
case '\t':
{
PRUnichar thePrevChar = theChar;
theChar = (++current != end) ? *current : '\0';
if ((thePrevChar == '\r' && theChar == '\n') ||
(thePrevChar == '\n' && theChar == '\r')) {
theChar = (++current != end) ? *current : '\0'; // CRLF == LFCR => LF
}
}
break;
default:
done = PR_TRUE;
AppendUnicodeTo(origin, current, aString);
break;
}
}
++current;
}
SetPosition(current);
if (current == end) {
AppendUnicodeTo(origin, current, aString);
return Eof();
result = Eof();
}
//DoErrTest(aString);
return result;
}
nsresult nsScanner::ReadWhitespace(nsReadingIterator<PRUnichar>& aStart,
nsReadingIterator<PRUnichar>& aEnd) {
nsReadingIterator<PRUnichar>& aEnd,
PRInt32& aNewlinesSkipped) {
if (!mSlidingBuffer) {
return kEOF;
}
PRUnichar theChar=0;
nsresult result=Peek(theChar);
PRUnichar theChar = 0;
nsresult result = Peek(theChar);
if (result == kEOF) {
return Eof();
}
nsReadingIterator<PRUnichar> origin, current, end;
PRBool found=PR_FALSE;
PRBool done = PR_FALSE;
origin = mCurrentPosition;
current = origin;
end = mEndPosition;
while(current != end) {
theChar=*current;
if(theChar) {
switch(theChar) {
case ' ':
case '\b':
case '\t':
case kLF:
case kCR:
found=PR_TRUE;
break;
default:
found=PR_FALSE;
break;
}
if(!found) {
while(!done && current != end) {
switch(theChar) {
case '\n':
case '\r': aNewlinesSkipped++;
case ' ' :
case '\b':
case '\t':
{
PRUnichar thePrevChar = theChar;
theChar = (++current != end) ? *current : '\0';
if ((thePrevChar == '\r' && theChar == '\n') ||
(thePrevChar == '\n' && theChar == '\r')) {
theChar = (++current != end) ? *current : '\0'; // CRLF == LFCR => LF
}
}
break;
default:
done = PR_TRUE;
aStart = origin;
aEnd = current;
break;
}
++current;
}
}
@ -1122,11 +1125,9 @@ nsresult nsScanner::ReadWhitespace(nsReadingIterator<PRUnichar>& aStart,
if (current == end) {
aStart = origin;
aEnd = current;
return Eof();
result = Eof();
}
//DoErrTest(aString);
return result;
}

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

@ -185,7 +185,7 @@ class nsScanner {
* @update gess 3/25/98
* @return error status
*/
nsresult SkipWhitespace(void);
nsresult SkipWhitespace(PRInt32& aNewlinesSkipped);
/**
* Determine if the scanner has reached EOF.
@ -214,9 +214,11 @@ class nsScanner {
nsresult ReadNumber(nsReadingIterator<PRUnichar>& aStart,
nsReadingIterator<PRUnichar>& aEnd,
PRInt32 aBase);
nsresult ReadWhitespace(nsString& aString);
nsresult ReadWhitespace(nsString& aString,
PRInt32& aNewlinesSkipped);
nsresult ReadWhitespace(nsReadingIterator<PRUnichar>& aStart,
nsReadingIterator<PRUnichar>& aEnd);
nsReadingIterator<PRUnichar>& aEnd,
PRInt32& aNewlinesSkipped);
/**
* Consume characters until you find the terminal char
@ -363,8 +365,6 @@ class nsScanner {
PRBool IsIncremental(void) {return mIncremental;}
void SetIncremental(PRBool anIncrValue) {mIncremental=anIncrValue;}
PRInt32 GetNewlinesSkipped(void) { return mNewlinesSkipped; }
protected:
@ -396,7 +396,6 @@ class nsScanner {
PRInt32 mCharsetSource;
nsString mCharset;
nsIUnicodeDecoder *mUnicodeDecoder;
PRInt32 mNewlinesSkipped;
};
#endif

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

@ -67,6 +67,7 @@ CToken::CToken(PRInt32 aTag) {
#endif
mAttrCount=0;
mNewlineCount=0;
mLineNumber = 0;
mTypeID=aTag;
// Note that the use count starts with 1 instead of 0. This
// is because of the assumption that any token created is in
@ -156,7 +157,7 @@ void CToken::GetSource(nsString& anOutputString){
* @update harishd 3/23/00
* @return reference to string containing string value
*/
void CToken::AppendSource(nsString& anOutputString){
void CToken::AppendSourceTo(nsAString& anOutputString){
anOutputString.Append(GetStringValue());
}
@ -182,16 +183,6 @@ PRInt32 CToken::GetTypeID(void) {
return mTypeID;
}
/**
* Sets the attribute count for this token
*
* @update gess 3/25/98
* @param value -- new attr count
*/
void CToken::SetAttributeCount(PRInt16 value) {
mAttrCount=value;
}
/**
* Retrieves copy of attr count for this token
*

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

@ -380,9 +380,6 @@ CViewSourceHTML::CViewSourceHTML() : mFilename(), mTags(), mErrors() {
*/
CViewSourceHTML::~CViewSourceHTML(){
mParser=0; //just to prove we destructed...
NS_IF_RELEASE(mTokenizer);
}
/**
@ -454,7 +451,9 @@ CViewSourceHTML::CanParse(CParserContext& aParserContext,
* @param aSink
* @return error code (almost always 0)
*/
nsresult CViewSourceHTML::WillBuildModel( const CParserContext& aParserContext,nsIContentSink* aSink){
nsresult CViewSourceHTML::WillBuildModel(const CParserContext& aParserContext,
nsITokenizer* aTokenizer,
nsIContentSink* aSink){
nsresult result=NS_OK;
@ -476,6 +475,7 @@ nsresult CViewSourceHTML::WillBuildModel( const CParserContext& aParserContext,
mMimeType=aParserContext.mMimeType;
mDTDMode=aParserContext.mDTDMode;
mParserCommand=aParserContext.mParserCommand;
mTokenizer = aTokenizer;
mErrorCount=0;
mTagCount=0;
@ -535,12 +535,12 @@ NS_IMETHODIMP CViewSourceHTML::BuildModel(nsIParser* aParser,nsITokenizer* aToke
tag.Assign(NS_LITERAL_STRING("HTML"));
CStartToken htmlToken(tag, eHTMLTag_html);
nsCParserNode htmlNode(&htmlToken,0,0/*stack token*/);
nsCParserNode htmlNode(&htmlToken, 0/*stack token*/);
mSink->OpenHTML(htmlNode);
tag.Assign(NS_LITERAL_STRING("HEAD"));
CStartToken headToken(tag, eHTMLTag_head);
nsCParserNode headNode(&headToken,0,0/*stack token*/);
nsCParserNode headNode(&headToken, 0/*stack token*/);
mSink->OpenHead(headNode);
// Note that XUL with automatically add the prefix "Source of: "
@ -551,7 +551,7 @@ NS_IMETHODIMP CViewSourceHTML::BuildModel(nsIParser* aParser,nsITokenizer* aToke
CStartToken* theToken=NS_STATIC_CAST(CStartToken*,theAllocator->CreateTokenOfType(eToken_start,eHTMLTag_link,tag));
if(theToken) {
CAttributeToken *theAttr;
nsCParserNode theNode(theToken,0,theAllocator);
nsCParserNode theNode(theToken, theAllocator);
theAttr=(CAttributeToken*)theAllocator->CreateTokenOfType(eToken_attribute,eHTMLTag_unknown,NS_LITERAL_STRING("stylesheet"));
theAttr->SetKey(NS_LITERAL_STRING("rel"));
@ -571,7 +571,7 @@ NS_IMETHODIMP CViewSourceHTML::BuildModel(nsIParser* aParser,nsITokenizer* aToke
}
CEndToken endHeadToken(eHTMLTag_head);
nsCParserNode endHeadNode(&endHeadToken,0,0/*stack token*/);
nsCParserNode endHeadNode(&endHeadToken, 0/*stack token*/);
result = mSink->CloseHead(endHeadNode);
if(NS_SUCCEEDED(result)) {
mHasOpenRoot = PR_TRUE;
@ -585,7 +585,7 @@ NS_IMETHODIMP CViewSourceHTML::BuildModel(nsIParser* aParser,nsITokenizer* aToke
tag.Assign(NS_LITERAL_STRING("BODY"));
CStartToken* bodyToken=NS_STATIC_CAST(CStartToken*,theAllocator->CreateTokenOfType(eToken_start, eHTMLTag_body, tag));
if (bodyToken) {
nsCParserNode bodyNode(bodyToken,0,theAllocator);
nsCParserNode bodyNode(bodyToken, theAllocator);
CAttributeToken *theAttr=nsnull;
theAttr=(CAttributeToken*)theAllocator->CreateTokenOfType(eToken_attribute,eHTMLTag_unknown,NS_ConvertASCIItoUCS2(kBodyId));
theAttr->SetKey(NS_LITERAL_STRING("id"));
@ -603,7 +603,7 @@ NS_IMETHODIMP CViewSourceHTML::BuildModel(nsIParser* aParser,nsITokenizer* aToke
if (NS_SUCCEEDED(result)) {
CStartToken theToken(eHTMLTag_pre);
nsCParserNode theNode(&theToken,0,0/*stack token*/);
nsCParserNode theNode(&theToken, 0/*stack token*/);
result=mSink->OpenContainer(theNode);
}
}
@ -664,11 +664,11 @@ nsresult CViewSourceHTML::GenerateSummary() {
*/
void CViewSourceHTML::StartNewPreBlock(void){
CEndToken endToken(eHTMLTag_pre);
nsCParserNode endNode(&endToken,0,0/*stack token*/);
nsCParserNode endNode(&endToken, 0/*stack token*/);
mSink->CloseContainer(endNode);
CStartToken startToken(eHTMLTag_pre);
nsCParserNode startNode(&startToken,0,0/*stack token*/);
nsCParserNode startNode(&startToken, 0/*stack token*/);
mSink->OpenContainer(startNode);
#ifdef DUMP_TO_FILE
@ -712,15 +712,15 @@ NS_IMETHODIMP CViewSourceHTML::DidBuildModel(nsresult anErrorCode,PRBool aNotify
if(ePlainText!=mDocType) {
CEndToken theToken(eHTMLTag_pre);
nsCParserNode preNode(&theToken,0,0/*stack token*/);
nsCParserNode preNode(&theToken, 0/*stack token*/);
mSink->CloseContainer(preNode);
CEndToken bodyToken(eHTMLTag_body);
nsCParserNode bodyNode(&bodyToken,0,0/*stack token*/);
nsCParserNode bodyNode(&bodyToken, 0/*stack token*/);
mSink->CloseBody(bodyNode);
CEndToken htmlToken(eHTMLTag_html);
nsCParserNode htmlNode(&htmlToken,0,0/*stack token*/);
nsCParserNode htmlNode(&htmlToken, 0/*stack token*/);
mSink->CloseHTML(htmlNode);
}
result = mSink->DidBuildModel(1);
@ -754,23 +754,16 @@ NS_IMETHODIMP_(void)
CViewSourceHTML::Terminate() {
}
/**
* Retrieve the preferred tokenizer for use by this DTD.
* @update gess12/28/98
* @param none
* @return ptr to tokenizer
*/
nsresult CViewSourceHTML::GetTokenizer(nsITokenizer*& aTokenizer) {
nsresult result=NS_OK;
if(!mTokenizer) {
result=NS_NewHTMLTokenizer(&mTokenizer,eDTDMode_quirks,mDocType,mParserCommand);
}
aTokenizer=mTokenizer;
return result;
NS_IMETHODIMP_(PRInt32)
CViewSourceHTML::GetType() {
return NS_IPARSER_FLAG_HTML;
}
NS_IMETHODIMP
CViewSourceHTML::CollectSkippedContent(PRInt32 aTag, nsAString& aContent, PRInt32 &aLineNo)
{
return NS_OK;
}
/**
*
@ -946,7 +939,7 @@ nsresult CViewSourceHTML::WriteTag(PRInt32 aTagType,const nsAString & aText,PRIn
nsAutoString beforeText;
beforeText.AssignWithConversion(kBeforeText[aTagType]);
theContext.mITextToken.SetIndirectString(beforeText);
nsCParserNode theNode(&theContext.mITextToken,0,0/*stack token*/);
nsCParserNode theNode(&theContext.mITextToken, 0/*stack token*/);
mSink->AddLeaf(theNode);
}
#ifdef DUMP_TO_FILE
@ -957,7 +950,7 @@ nsresult CViewSourceHTML::WriteTag(PRInt32 aTagType,const nsAString & aText,PRIn
if (mSyntaxHighlight && aTagType != mText) {
CStartToken* theTagToken=NS_STATIC_CAST(CStartToken*,theAllocator->CreateTokenOfType(eToken_start,eHTMLTag_span,NS_LITERAL_STRING("SPAN")));
theContext.mStartNode.Init(theTagToken,mLineNumber,theAllocator);
theContext.mStartNode.Init(theTagToken, theAllocator);
CAttributeToken* theAttr=(CAttributeToken*)theAllocator->CreateTokenOfType(eToken_attribute,eHTMLTag_unknown,NS_ConvertASCIItoUCS2(kElementClasses[aTagType]));
theAttr->SetKey(NS_LITERAL_STRING("class"));
theContext.mStartNode.AddAttribute(theAttr);
@ -975,7 +968,7 @@ nsresult CViewSourceHTML::WriteTag(PRInt32 aTagType,const nsAString & aText,PRIn
theContext.mITextToken.SetIndirectString(aText); //now emit the tag name...
nsCParserNode theNode(&theContext.mITextToken,0,0/*stack token*/);
nsCParserNode theNode(&theContext.mITextToken, 0/*stack token*/);
mSink->AddLeaf(theNode);
#ifdef DUMP_TO_FILE
if (gDumpFile) {
@ -988,7 +981,7 @@ nsresult CViewSourceHTML::WriteTag(PRInt32 aTagType,const nsAString & aText,PRIn
if (mSyntaxHighlight && aTagType != mText) {
theContext.mStartNode.ReleaseAll();
CEndToken theEndToken(eHTMLTag_span);
theContext.mEndNode.Init(&theEndToken,mLineNumber,0/*stack token*/);
theContext.mEndNode.Init(&theEndToken, 0/*stack token*/);
mSink->CloseContainer(theContext.mEndNode); //emit </starttag>...
#ifdef DUMP_TO_FILE
if (gDumpFile)
@ -1004,7 +997,7 @@ nsresult CViewSourceHTML::WriteTag(PRInt32 aTagType,const nsAString & aText,PRIn
nsAutoString afterText;
afterText.AssignWithConversion(kAfterText[aTagType]);
theContext.mITextToken.SetIndirectString(afterText);
nsCParserNode theNode(&theContext.mITextToken,0,0/*stack token*/);
nsCParserNode theNode(&theContext.mITextToken, 0/*stack token*/);
mSink->AddLeaf(theNode);
}
#ifdef DUMP_TO_FILE
@ -1033,7 +1026,7 @@ NS_IMETHODIMP CViewSourceHTML::HandleToken(CToken* aToken,nsIParser* aParser) {
mSink=(nsIHTMLContentSink*)aParser->GetContentSink();
CSharedVSContext& theContext=CSharedVSContext::GetSharedContext();
theContext.mTokenNode.Init(theToken,mLineNumber,mTokenizer->GetTokenAllocator());
theContext.mTokenNode.Init(theToken, mTokenizer->GetTokenAllocator());
eHTMLTags theParent=(mTags.Length()) ? (eHTMLTags)mTags.Last() : eHTMLTag_unknown;
eHTMLTags theChild=(eHTMLTags)aToken->GetTypeID();
@ -1058,8 +1051,9 @@ NS_IMETHODIMP CViewSourceHTML::HandleToken(CToken* aToken,nsIParser* aParser) {
if(theParent==theChild) {
mTags.Truncate(mTags.Length()-1);
}
const nsAString& endValue = aToken->GetStringValue();
result=WriteTag(mEndTag,endValue,0,PR_TRUE);
result=WriteTag(mEndTag,endValue,aToken->GetAttributeCount(),PR_TRUE);
}
break;

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

@ -82,7 +82,7 @@ protected:
nsParser* mParser;
nsIHTMLContentSink* mSink;
PRInt32 mLineNumber;
nsITokenizer* mTokenizer;
nsITokenizer* mTokenizer; // weak
PRInt32 mStartTag;
PRInt32 mEndTag;