Put line number ids on all the <pre> blocks that we create; this should make it

easier to hook up a performant "go to line" UI.  Bug 104383, r+sr=rbs, a=asa
This commit is contained in:
bzbarsky%mit.edu 2003-05-17 16:15:30 +00:00
parent b84cf009ec
commit fe536ead5e
4 changed files with 240 additions and 118 deletions

View File

@ -81,6 +81,7 @@
#include "nsIPrefService.h"
#include "nsIPrefBranch.h"
#include "nsUnicharUtils.h"
#include "nsPrintfCString.h"
#include "nsIServiceManager.h"
@ -355,10 +356,10 @@ CViewSourceHTML::CViewSourceHTML() : mFilename(), mTags(), mErrors() {
mWrapLongLines = NS_SUCCEEDED(rv) ? temp : PR_FALSE;
}
mParser=0;
mSink=0;
mLineNumber=0;
mTokenizer=0;
mParser = 0;
mSink = 0;
mLineNumber = 1;
mTokenizer = 0;
mDocType=eHTML3_Quirks; // why?
mHasOpenRoot=PR_FALSE;
mHasOpenBody=PR_FALSE;
@ -498,7 +499,7 @@ nsresult CViewSourceHTML::WillBuildModel(const CParserContext& aParserContext,
fprintf(gDumpFile, "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">\n");
fprintf(gDumpFile, "</head>\n");
fprintf(gDumpFile, "<body id=\"viewsource\">\n");
fprintf(gDumpFile, "<pre>\n");
fprintf(gDumpFile, "<pre id=\"line1\">\n");
}
#endif //DUMP_TO_FILE
}
@ -508,7 +509,7 @@ nsresult CViewSourceHTML::WillBuildModel(const CParserContext& aParserContext,
mDocType=ePlainText;
else mDocType=aParserContext.mDocType;
mLineNumber=0;
mLineNumber = 1;
result = mSink->WillBuildModel();
START_TIMER();
@ -531,20 +532,17 @@ NS_IMETHODIMP CViewSourceHTML::BuildModel(nsIParser* aParser,nsITokenizer* aToke
nsITokenizer* oldTokenizer=mTokenizer;
mTokenizer=aTokenizer;
nsTokenAllocator* theAllocator=mTokenizer->GetTokenAllocator();
nsAutoString tag;
if(!mHasOpenRoot) {
// For the stack-allocated tokens below, it's safe to pass a null
// token allocator, because there are no attributes on the tokens.
PRBool didBlock = PR_FALSE;
tag.Assign(NS_LITERAL_STRING("HTML"));
CStartToken htmlToken(tag, eHTMLTag_html);
CStartToken htmlToken(NS_LITERAL_STRING("HTML"), eHTMLTag_html);
nsCParserNode htmlNode(&htmlToken, 0/*stack token*/);
mSink->OpenHTML(htmlNode);
tag.Assign(NS_LITERAL_STRING("HEAD"));
CStartToken headToken(tag, eHTMLTag_head);
CStartToken headToken(NS_LITERAL_STRING("HEAD"), eHTMLTag_head);
nsCParserNode headNode(&headToken, 0/*stack token*/);
mSink->OpenHead(headNode);
@ -559,24 +557,26 @@ NS_IMETHODIMP CViewSourceHTML::BuildModel(nsIParser* aParser,nsITokenizer* aToke
}
if (theAllocator) {
tag.Assign(NS_LITERAL_STRING("LINK"));
CStartToken* theToken=NS_STATIC_CAST(CStartToken*,theAllocator->CreateTokenOfType(eToken_start,eHTMLTag_link,tag));
if(theToken) {
CAttributeToken *theAttr;
CStartToken* theToken=
NS_STATIC_CAST(CStartToken*,
theAllocator->CreateTokenOfType(eToken_start,
eHTMLTag_link,
NS_LITERAL_STRING("LINK")));
if (theToken) {
nsCParserStartNode theNode(theToken, theAllocator);
theAttr=(CAttributeToken*)theAllocator->CreateTokenOfType(eToken_attribute,eHTMLTag_unknown,NS_LITERAL_STRING("stylesheet"));
theAttr->SetKey(NS_LITERAL_STRING("rel"));
theNode.AddAttribute(theAttr);
AddAttrToNode(theNode, theAllocator,
NS_LITERAL_STRING("rel"),
NS_LITERAL_STRING("stylesheet"));
theAttr=(CAttributeToken*)theAllocator->CreateTokenOfType(eToken_attribute,eHTMLTag_unknown,NS_LITERAL_STRING("text/css"));
theAttr->SetKey(NS_LITERAL_STRING("type"));
theNode.AddAttribute(theAttr);
theAttr=(CAttributeToken*)theAllocator->CreateTokenOfType(eToken_attribute,eHTMLTag_unknown,NS_LITERAL_STRING("resource:/res/viewsource.css"));
theAttr->SetKey(NS_LITERAL_STRING("href"));
theNode.AddAttribute(theAttr);
AddAttrToNode(theNode, theAllocator,
NS_LITERAL_STRING("type"),
NS_LITERAL_STRING("text/css"));
AddAttrToNode(theNode, theAllocator,
NS_LITERAL_STRING("href"),
NS_LITERAL_STRING("resource:/res/viewsource.css"));
result = mSink->AddLeaf(theNode);
didBlock = result == NS_ERROR_HTMLPARSER_BLOCK;
}
@ -593,30 +593,43 @@ NS_IMETHODIMP CViewSourceHTML::BuildModel(nsIParser* aParser,nsITokenizer* aToke
}
}
if (NS_SUCCEEDED(result) && !mHasOpenBody) {
if(theAllocator) {
tag.Assign(NS_LITERAL_STRING("BODY"));
CStartToken* bodyToken=NS_STATIC_CAST(CStartToken*,theAllocator->CreateTokenOfType(eToken_start, eHTMLTag_body, tag));
if (theAllocator) {
CStartToken* bodyToken=
NS_STATIC_CAST(CStartToken*,
theAllocator->CreateTokenOfType(eToken_start,
eHTMLTag_body,
NS_LITERAL_STRING("BODY")));
if (bodyToken) {
nsCParserStartNode bodyNode(bodyToken, theAllocator);
CAttributeToken *theAttr=nsnull;
theAttr=(CAttributeToken*)theAllocator->CreateTokenOfType(eToken_attribute,eHTMLTag_unknown,NS_ConvertASCIItoUCS2(kBodyId));
theAttr->SetKey(NS_LITERAL_STRING("id"));
bodyNode.AddAttribute(theAttr);
AddAttrToNode(bodyNode, theAllocator,
NS_LITERAL_STRING("id"),
NS_ConvertASCIItoUCS2(kBodyId));
if (mWrapLongLines) {
theAttr=(CAttributeToken*)theAllocator->CreateTokenOfType(eToken_attribute,eHTMLTag_unknown,NS_ConvertASCIItoUCS2(kBodyClassWrap));
theAttr->SetKey(NS_LITERAL_STRING("class"));
bodyNode.AddAttribute(theAttr);
AddAttrToNode(bodyNode, theAllocator,
NS_LITERAL_STRING("class"),
NS_ConvertASCIItoUCS2(kBodyClassWrap));
}
result = mSink->OpenBody(bodyNode);
if(NS_SUCCEEDED(result)) mHasOpenBody=PR_TRUE;
}
IF_FREE(bodyToken,theAllocator);
if (NS_SUCCEEDED(result)) {
CStartToken theToken(eHTMLTag_pre);
nsCParserNode theNode(&theToken, 0/*stack token*/);
result=mSink->OpenContainer(theNode);
CStartToken* preToken =
NS_STATIC_CAST(CStartToken*,
theAllocator->CreateTokenOfType(eToken_start,
eHTMLTag_pre,
NS_LITERAL_STRING("PRE")));
if (preToken) {
nsCParserStartNode preNode(preToken, theAllocator);
AddAttrToNode(preNode, theAllocator,
NS_LITERAL_STRING("id"),
NS_LITERAL_STRING("line1"));
result = mSink->OpenContainer(preNode);
} else {
result = NS_ERROR_OUT_OF_MEMORY;
}
}
}
}
@ -679,20 +692,56 @@ void CViewSourceHTML::StartNewPreBlock(void){
nsCParserNode endNode(&endToken, 0/*stack token*/);
mSink->CloseContainer(eHTMLTag_pre);
CStartToken startToken(eHTMLTag_pre);
nsCParserNode startNode(&startToken, 0/*stack token*/);
mSink->OpenContainer(startNode);
nsTokenAllocator* theAllocator = mTokenizer->GetTokenAllocator();
if (!theAllocator) {
return;
}
CStartToken* theToken =
NS_STATIC_CAST(CStartToken*,
theAllocator->CreateTokenOfType(eToken_start,
eHTMLTag_pre,
NS_LITERAL_STRING("PRE")));
if (!theToken) {
return;
}
nsCParserStartNode startNode(theToken, theAllocator);
AddAttrToNode(startNode, theAllocator,
NS_LITERAL_STRING("id"),
NS_ConvertASCIItoUCS2(nsPrintfCString("line%d", mLineNumber)));
mSink->OpenContainer(startNode);
#ifdef DUMP_TO_FILE
if (gDumpFile) {
fprintf(gDumpFile, "</pre>");
fprintf(gDumpFile, "<pre>");
fprintf(gDumpFile, "</pre>\n");
fprintf(gDumpFile, "<pre id=\"line%d\">\n", mLineNumber);
}
#endif // DUMP_TO_FILE
mTokenCount = 0;
}
void CViewSourceHTML::AddAttrToNode(nsCParserStartNode& aNode,
nsTokenAllocator* aAllocator,
const nsAString& aAttrName,
const nsAString& aAttrValue)
{
NS_PRECONDITION(aAllocator, "Must have a token allocator!");
CAttributeToken* theAttr =
(CAttributeToken*) aAllocator->CreateTokenOfType(eToken_attribute,
eHTMLTag_unknown,
aAttrValue);
if (!theAttr) {
NS_ERROR("Failed to allocate attribute token");
return;
}
theAttr->SetKey(aAttrName);
aNode.AddAttribute(theAttr);
}
/**
*
* @update gess5/18/98
@ -891,23 +940,23 @@ nsresult CViewSourceHTML::WriteAttributes(PRInt32 attrCount) {
CSharedVSContext& theContext=CSharedVSContext::GetSharedContext();
int attr=0;
for(attr=0;attr<attrCount;++attr){
CToken* theToken=mTokenizer->PeekToken();
int attr = 0;
for(attr = 0; attr < attrCount; ++attr){
CToken* theToken = mTokenizer->PeekToken();
if(theToken) {
eHTMLTokenTypes theType=eHTMLTokenTypes(theToken->GetTokenType());
if(eToken_attribute==theType){
eHTMLTokenTypes theType = eHTMLTokenTypes(theToken->GetTokenType());
if(eToken_attribute == theType){
mTokenizer->PopToken(); //pop it for real...
theContext.mTokenNode.AddAttribute(theToken); //and add it to the node.
CAttributeToken* theAttrToken=(CAttributeToken*)theToken;
const nsAString& theKey=theAttrToken->GetKey();
CAttributeToken* theAttrToken = (CAttributeToken*)theToken;
const nsAString& theKey = theAttrToken->GetKey();
result=WriteTag(mKey,theKey,0,PR_FALSE);
const nsAString& theValue=theAttrToken->GetValue();
result = WriteTag(mKey,theKey,0,PR_FALSE);
const nsAString& theValue = theAttrToken->GetValue();
if((0<theValue.Length()) || (theAttrToken->mHasEqualWithoutValue)){
result=WriteTag(mValue,theValue,0,PR_FALSE);
if(!theValue.IsEmpty() || theAttrToken->mHasEqualWithoutValue){
result = WriteTag(mValue,theValue,0,PR_FALSE);
}
}
}
@ -930,6 +979,14 @@ nsresult CViewSourceHTML::WriteTag(PRInt32 aTagType,const nsAString & aText,PRIn
nsresult result=NS_OK;
// adjust line number to what it will be after we finish writing this tag
// XXXbz life here sucks. We can't use the GetNewlineCount on the token,
// because Text tokens in <style>, <script>, etc lie through their teeth.
// On the other hand, the parser messes up newline counting in some token
// types (bug 137315). So our line numbers will disagree with the parser's
// in some cases...
mLineNumber += aText.CountChar(PRUnichar('\n'));
CSharedVSContext& theContext=CSharedVSContext::GetSharedContext();
nsTokenAllocator* theAllocator=mTokenizer->GetTokenAllocator();
@ -953,9 +1010,9 @@ nsresult CViewSourceHTML::WriteTag(PRInt32 aTagType,const nsAString & aText,PRIn
CStartToken* theTagToken=NS_STATIC_CAST(CStartToken*,theAllocator->CreateTokenOfType(eToken_start,eHTMLTag_span,NS_LITERAL_STRING("SPAN")));
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);
AddAttrToNode(theContext.mStartNode, theAllocator,
NS_LITERAL_STRING("class"),
NS_ConvertASCIItoUCS2(kElementClasses[aTagType]));
mSink->OpenContainer(theContext.mStartNode); //emit <starttag>...
#ifdef DUMP_TO_FILE
if (gDumpFile) {
@ -1095,7 +1152,6 @@ NS_IMETHODIMP CViewSourceHTML::HandleToken(CToken* aToken,nsIParser* aParser) {
case eToken_newline:
{
const nsAString& newlineValue = aToken->GetStringValue();
++mLineNumber;
result=WriteTag(mText,newlineValue,0,PR_FALSE);
++mTokenCount;
if (NS_VIEWSOURCE_TOKENS_PER_BLOCK > 0 &&

View File

@ -76,6 +76,11 @@ private:
nsresult WriteAttributes(PRInt32 attrCount);
nsresult GenerateSummary();
void StartNewPreBlock(void);
// Utility method for adding attributes to the nodes we generate
void AddAttrToNode(nsCParserStartNode& aNode,
nsTokenAllocator* aAllocator,
const nsAString& aAttrName,
const nsAString& aAttrValue);
protected:

View File

@ -81,6 +81,7 @@
#include "nsIPrefService.h"
#include "nsIPrefBranch.h"
#include "nsUnicharUtils.h"
#include "nsPrintfCString.h"
#include "nsIServiceManager.h"
@ -355,10 +356,10 @@ CViewSourceHTML::CViewSourceHTML() : mFilename(), mTags(), mErrors() {
mWrapLongLines = NS_SUCCEEDED(rv) ? temp : PR_FALSE;
}
mParser=0;
mSink=0;
mLineNumber=0;
mTokenizer=0;
mParser = 0;
mSink = 0;
mLineNumber = 1;
mTokenizer = 0;
mDocType=eHTML3_Quirks; // why?
mHasOpenRoot=PR_FALSE;
mHasOpenBody=PR_FALSE;
@ -498,7 +499,7 @@ nsresult CViewSourceHTML::WillBuildModel(const CParserContext& aParserContext,
fprintf(gDumpFile, "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">\n");
fprintf(gDumpFile, "</head>\n");
fprintf(gDumpFile, "<body id=\"viewsource\">\n");
fprintf(gDumpFile, "<pre>\n");
fprintf(gDumpFile, "<pre id=\"line1\">\n");
}
#endif //DUMP_TO_FILE
}
@ -508,7 +509,7 @@ nsresult CViewSourceHTML::WillBuildModel(const CParserContext& aParserContext,
mDocType=ePlainText;
else mDocType=aParserContext.mDocType;
mLineNumber=0;
mLineNumber = 1;
result = mSink->WillBuildModel();
START_TIMER();
@ -531,20 +532,17 @@ NS_IMETHODIMP CViewSourceHTML::BuildModel(nsIParser* aParser,nsITokenizer* aToke
nsITokenizer* oldTokenizer=mTokenizer;
mTokenizer=aTokenizer;
nsTokenAllocator* theAllocator=mTokenizer->GetTokenAllocator();
nsAutoString tag;
if(!mHasOpenRoot) {
// For the stack-allocated tokens below, it's safe to pass a null
// token allocator, because there are no attributes on the tokens.
PRBool didBlock = PR_FALSE;
tag.Assign(NS_LITERAL_STRING("HTML"));
CStartToken htmlToken(tag, eHTMLTag_html);
CStartToken htmlToken(NS_LITERAL_STRING("HTML"), eHTMLTag_html);
nsCParserNode htmlNode(&htmlToken, 0/*stack token*/);
mSink->OpenHTML(htmlNode);
tag.Assign(NS_LITERAL_STRING("HEAD"));
CStartToken headToken(tag, eHTMLTag_head);
CStartToken headToken(NS_LITERAL_STRING("HEAD"), eHTMLTag_head);
nsCParserNode headNode(&headToken, 0/*stack token*/);
mSink->OpenHead(headNode);
@ -559,24 +557,26 @@ NS_IMETHODIMP CViewSourceHTML::BuildModel(nsIParser* aParser,nsITokenizer* aToke
}
if (theAllocator) {
tag.Assign(NS_LITERAL_STRING("LINK"));
CStartToken* theToken=NS_STATIC_CAST(CStartToken*,theAllocator->CreateTokenOfType(eToken_start,eHTMLTag_link,tag));
if(theToken) {
CAttributeToken *theAttr;
CStartToken* theToken=
NS_STATIC_CAST(CStartToken*,
theAllocator->CreateTokenOfType(eToken_start,
eHTMLTag_link,
NS_LITERAL_STRING("LINK")));
if (theToken) {
nsCParserStartNode theNode(theToken, theAllocator);
theAttr=(CAttributeToken*)theAllocator->CreateTokenOfType(eToken_attribute,eHTMLTag_unknown,NS_LITERAL_STRING("stylesheet"));
theAttr->SetKey(NS_LITERAL_STRING("rel"));
theNode.AddAttribute(theAttr);
AddAttrToNode(theNode, theAllocator,
NS_LITERAL_STRING("rel"),
NS_LITERAL_STRING("stylesheet"));
theAttr=(CAttributeToken*)theAllocator->CreateTokenOfType(eToken_attribute,eHTMLTag_unknown,NS_LITERAL_STRING("text/css"));
theAttr->SetKey(NS_LITERAL_STRING("type"));
theNode.AddAttribute(theAttr);
theAttr=(CAttributeToken*)theAllocator->CreateTokenOfType(eToken_attribute,eHTMLTag_unknown,NS_LITERAL_STRING("resource:/res/viewsource.css"));
theAttr->SetKey(NS_LITERAL_STRING("href"));
theNode.AddAttribute(theAttr);
AddAttrToNode(theNode, theAllocator,
NS_LITERAL_STRING("type"),
NS_LITERAL_STRING("text/css"));
AddAttrToNode(theNode, theAllocator,
NS_LITERAL_STRING("href"),
NS_LITERAL_STRING("resource:/res/viewsource.css"));
result = mSink->AddLeaf(theNode);
didBlock = result == NS_ERROR_HTMLPARSER_BLOCK;
}
@ -593,30 +593,43 @@ NS_IMETHODIMP CViewSourceHTML::BuildModel(nsIParser* aParser,nsITokenizer* aToke
}
}
if (NS_SUCCEEDED(result) && !mHasOpenBody) {
if(theAllocator) {
tag.Assign(NS_LITERAL_STRING("BODY"));
CStartToken* bodyToken=NS_STATIC_CAST(CStartToken*,theAllocator->CreateTokenOfType(eToken_start, eHTMLTag_body, tag));
if (theAllocator) {
CStartToken* bodyToken=
NS_STATIC_CAST(CStartToken*,
theAllocator->CreateTokenOfType(eToken_start,
eHTMLTag_body,
NS_LITERAL_STRING("BODY")));
if (bodyToken) {
nsCParserStartNode bodyNode(bodyToken, theAllocator);
CAttributeToken *theAttr=nsnull;
theAttr=(CAttributeToken*)theAllocator->CreateTokenOfType(eToken_attribute,eHTMLTag_unknown,NS_ConvertASCIItoUCS2(kBodyId));
theAttr->SetKey(NS_LITERAL_STRING("id"));
bodyNode.AddAttribute(theAttr);
AddAttrToNode(bodyNode, theAllocator,
NS_LITERAL_STRING("id"),
NS_ConvertASCIItoUCS2(kBodyId));
if (mWrapLongLines) {
theAttr=(CAttributeToken*)theAllocator->CreateTokenOfType(eToken_attribute,eHTMLTag_unknown,NS_ConvertASCIItoUCS2(kBodyClassWrap));
theAttr->SetKey(NS_LITERAL_STRING("class"));
bodyNode.AddAttribute(theAttr);
AddAttrToNode(bodyNode, theAllocator,
NS_LITERAL_STRING("class"),
NS_ConvertASCIItoUCS2(kBodyClassWrap));
}
result = mSink->OpenBody(bodyNode);
if(NS_SUCCEEDED(result)) mHasOpenBody=PR_TRUE;
}
IF_FREE(bodyToken,theAllocator);
if (NS_SUCCEEDED(result)) {
CStartToken theToken(eHTMLTag_pre);
nsCParserNode theNode(&theToken, 0/*stack token*/);
result=mSink->OpenContainer(theNode);
CStartToken* preToken =
NS_STATIC_CAST(CStartToken*,
theAllocator->CreateTokenOfType(eToken_start,
eHTMLTag_pre,
NS_LITERAL_STRING("PRE")));
if (preToken) {
nsCParserStartNode preNode(preToken, theAllocator);
AddAttrToNode(preNode, theAllocator,
NS_LITERAL_STRING("id"),
NS_LITERAL_STRING("line1"));
result = mSink->OpenContainer(preNode);
} else {
result = NS_ERROR_OUT_OF_MEMORY;
}
}
}
}
@ -679,20 +692,56 @@ void CViewSourceHTML::StartNewPreBlock(void){
nsCParserNode endNode(&endToken, 0/*stack token*/);
mSink->CloseContainer(eHTMLTag_pre);
CStartToken startToken(eHTMLTag_pre);
nsCParserNode startNode(&startToken, 0/*stack token*/);
mSink->OpenContainer(startNode);
nsTokenAllocator* theAllocator = mTokenizer->GetTokenAllocator();
if (!theAllocator) {
return;
}
CStartToken* theToken =
NS_STATIC_CAST(CStartToken*,
theAllocator->CreateTokenOfType(eToken_start,
eHTMLTag_pre,
NS_LITERAL_STRING("PRE")));
if (!theToken) {
return;
}
nsCParserStartNode startNode(theToken, theAllocator);
AddAttrToNode(startNode, theAllocator,
NS_LITERAL_STRING("id"),
NS_ConvertASCIItoUCS2(nsPrintfCString("line%d", mLineNumber)));
mSink->OpenContainer(startNode);
#ifdef DUMP_TO_FILE
if (gDumpFile) {
fprintf(gDumpFile, "</pre>");
fprintf(gDumpFile, "<pre>");
fprintf(gDumpFile, "</pre>\n");
fprintf(gDumpFile, "<pre id=\"line%d\">\n", mLineNumber);
}
#endif // DUMP_TO_FILE
mTokenCount = 0;
}
void CViewSourceHTML::AddAttrToNode(nsCParserStartNode& aNode,
nsTokenAllocator* aAllocator,
const nsAString& aAttrName,
const nsAString& aAttrValue)
{
NS_PRECONDITION(aAllocator, "Must have a token allocator!");
CAttributeToken* theAttr =
(CAttributeToken*) aAllocator->CreateTokenOfType(eToken_attribute,
eHTMLTag_unknown,
aAttrValue);
if (!theAttr) {
NS_ERROR("Failed to allocate attribute token");
return;
}
theAttr->SetKey(aAttrName);
aNode.AddAttribute(theAttr);
}
/**
*
* @update gess5/18/98
@ -891,23 +940,23 @@ nsresult CViewSourceHTML::WriteAttributes(PRInt32 attrCount) {
CSharedVSContext& theContext=CSharedVSContext::GetSharedContext();
int attr=0;
for(attr=0;attr<attrCount;++attr){
CToken* theToken=mTokenizer->PeekToken();
int attr = 0;
for(attr = 0; attr < attrCount; ++attr){
CToken* theToken = mTokenizer->PeekToken();
if(theToken) {
eHTMLTokenTypes theType=eHTMLTokenTypes(theToken->GetTokenType());
if(eToken_attribute==theType){
eHTMLTokenTypes theType = eHTMLTokenTypes(theToken->GetTokenType());
if(eToken_attribute == theType){
mTokenizer->PopToken(); //pop it for real...
theContext.mTokenNode.AddAttribute(theToken); //and add it to the node.
CAttributeToken* theAttrToken=(CAttributeToken*)theToken;
const nsAString& theKey=theAttrToken->GetKey();
CAttributeToken* theAttrToken = (CAttributeToken*)theToken;
const nsAString& theKey = theAttrToken->GetKey();
result=WriteTag(mKey,theKey,0,PR_FALSE);
const nsAString& theValue=theAttrToken->GetValue();
result = WriteTag(mKey,theKey,0,PR_FALSE);
const nsAString& theValue = theAttrToken->GetValue();
if((0<theValue.Length()) || (theAttrToken->mHasEqualWithoutValue)){
result=WriteTag(mValue,theValue,0,PR_FALSE);
if(!theValue.IsEmpty() || theAttrToken->mHasEqualWithoutValue){
result = WriteTag(mValue,theValue,0,PR_FALSE);
}
}
}
@ -930,6 +979,14 @@ nsresult CViewSourceHTML::WriteTag(PRInt32 aTagType,const nsAString & aText,PRIn
nsresult result=NS_OK;
// adjust line number to what it will be after we finish writing this tag
// XXXbz life here sucks. We can't use the GetNewlineCount on the token,
// because Text tokens in <style>, <script>, etc lie through their teeth.
// On the other hand, the parser messes up newline counting in some token
// types (bug 137315). So our line numbers will disagree with the parser's
// in some cases...
mLineNumber += aText.CountChar(PRUnichar('\n'));
CSharedVSContext& theContext=CSharedVSContext::GetSharedContext();
nsTokenAllocator* theAllocator=mTokenizer->GetTokenAllocator();
@ -953,9 +1010,9 @@ nsresult CViewSourceHTML::WriteTag(PRInt32 aTagType,const nsAString & aText,PRIn
CStartToken* theTagToken=NS_STATIC_CAST(CStartToken*,theAllocator->CreateTokenOfType(eToken_start,eHTMLTag_span,NS_LITERAL_STRING("SPAN")));
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);
AddAttrToNode(theContext.mStartNode, theAllocator,
NS_LITERAL_STRING("class"),
NS_ConvertASCIItoUCS2(kElementClasses[aTagType]));
mSink->OpenContainer(theContext.mStartNode); //emit <starttag>...
#ifdef DUMP_TO_FILE
if (gDumpFile) {
@ -1095,7 +1152,6 @@ NS_IMETHODIMP CViewSourceHTML::HandleToken(CToken* aToken,nsIParser* aParser) {
case eToken_newline:
{
const nsAString& newlineValue = aToken->GetStringValue();
++mLineNumber;
result=WriteTag(mText,newlineValue,0,PR_FALSE);
++mTokenCount;
if (NS_VIEWSOURCE_TOKENS_PER_BLOCK > 0 &&

View File

@ -76,6 +76,11 @@ private:
nsresult WriteAttributes(PRInt32 attrCount);
nsresult GenerateSummary();
void StartNewPreBlock(void);
// Utility method for adding attributes to the nodes we generate
void AddAttrToNode(nsCParserStartNode& aNode,
nsTokenAllocator* aAllocator,
const nsAString& aAttrName,
const nsAString& aAttrValue);
protected: