diff --git a/mozilla/parser/htmlparser/src/CNavDTD.cpp b/mozilla/parser/htmlparser/src/CNavDTD.cpp
index dca93296ca8..1d4a42eabd7 100644
--- a/mozilla/parser/htmlparser/src/CNavDTD.cpp
+++ b/mozilla/parser/htmlparser/src/CNavDTD.cpp
@@ -38,20 +38,17 @@
//#define ALLOW_TR_AS_CHILD_OF_TABLE //by setting this to true, TR is allowable directly in TABLE.
-#define ENABLE_RESIDUALSTYLE
-
-
#include "nsDebug.h"
#include "nsIAtom.h"
-#include "CNavDTD.h"
+#include "CNavDTD.h"
#include "nsHTMLTokens.h"
#include "nsCRT.h"
#include "nsParser.h"
#include "nsIParser.h"
-#include "nsIHTMLContentSink.h"
+#include "nsIHTMLContentSink.h"
#include "nsScanner.h"
-#include "prenv.h" //this is here for debug reasons...
-#include "prtypes.h" //this is here for debug reasons...
+#include "prenv.h"
+#include "prtypes.h"
#include "prio.h"
#include "plstr.h"
#include "nsDTDUtils.h"
@@ -74,16 +71,11 @@
/*
* Ignore kFontStyle and kPhrase tags when the stack is deep, bug 58917.
*/
-#define FONTSTYLE_IGNORE_DEPTH (MAX_REFLOW_DEPTH*80/100)
-#define PHRASE_IGNORE_DEPTH (MAX_REFLOW_DEPTH*90/100)
-
+#define FONTSTYLE_IGNORE_DEPTH (MAX_REFLOW_DEPTH * 80 / 100)
+#define PHRASE_IGNORE_DEPTH (MAX_REFLOW_DEPTH * 90 / 100)
-static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
-static NS_DEFINE_IID(kIDTDIID, NS_IDTD_IID);
-static NS_DEFINE_IID(kClassIID, NS_INAVHTML_DTD_IID);
+static NS_DEFINE_CID(kFormProcessorCID, NS_FORMPROCESSOR_CID);
-static NS_DEFINE_CID(kFormProcessorCID, NS_FORMPROCESSOR_CID);
-
#ifdef DEBUG
static const char kNullToken[] = "Error: Null token given";
static const char kInvalidTagStackPos[] = "Error: invalid tag stack position";
@@ -93,22 +85,18 @@ static const char kInvalidTagStackPos[] = "Error: invalid tag stack position";
#ifdef MOZ_PERF_METRICS
# define START_TIMER() \
- if(mParser) MOZ_TIMER_START(mParser->mParseTime); \
- if(mParser) MOZ_TIMER_START(mParser->mDTDTime);
+ if (mParser) MOZ_TIMER_START(mParser->mParseTime); \
+ if (mParser) MOZ_TIMER_START(mParser->mDTDTime);
# define STOP_TIMER() \
- if(mParser) MOZ_TIMER_STOP(mParser->mParseTime); \
- if(mParser) MOZ_TIMER_STOP(mParser->mDTDTime);
+ if (mParser) MOZ_TIMER_STOP(mParser->mParseTime); \
+ if (mParser) MOZ_TIMER_STOP(mParser->mDTDTime);
#else
# define STOP_TIMER()
# define START_TIMER()
#endif
-/************************************************************************
- And now for the main class -- CNavDTD...
- ************************************************************************/
-
-
+// Some flags for use by the DTD.
#define NS_DTD_FLAG_NONE 0x00000000
#define NS_DTD_FLAG_HAS_OPEN_HEAD 0x00000001
#define NS_DTD_FLAG_HAS_OPEN_BODY 0x00000002
@@ -125,55 +113,15 @@ static const char kInvalidTagStackPos[] = "Error: invalid tag stack position";
#define NS_DTD_FLAG_HAS_MAIN_CONTAINER (NS_DTD_FLAG_HAD_BODY | \
NS_DTD_FLAG_HAD_FRAMESET)
-/**
- * This method gets called as part of our COM-like interfaces.
- * Its purpose is to create an interface to parser object
- * of some type.
- *
- * @update gess 4/8/98
- * @param nsIID id of object to discover
- * @param aInstancePtr ptr to newly discovered interface
- * @return NS_xxx result code
- */
-nsresult CNavDTD::QueryInterface(const nsIID& aIID, void** aInstancePtr)
-{
- if (NULL == aInstancePtr) {
- return NS_ERROR_NULL_POINTER;
- }
+NS_IMPL_ISUPPORTS2(CNavDTD, nsIDTD, CNavDTD);
- if(aIID.Equals(kISupportsIID)) { //do IUnknown...
- *aInstancePtr = (nsIDTD*)(this);
- }
- else if(aIID.Equals(kIDTDIID)) { //do IParser base class...
- *aInstancePtr = (nsIDTD*)(this);
- }
- else if(aIID.Equals(kClassIID)) { //do this class...
- *aInstancePtr = (CNavDTD*)(this);
- }
- else {
- *aInstancePtr=0;
- return NS_NOINTERFACE;
- }
- NS_ADDREF_THIS();
- return NS_OK;
-}
-
-NS_IMPL_ADDREF(CNavDTD)
-NS_IMPL_RELEASE(CNavDTD)
-
-/**
- * Default constructor
- *
- * @update gess 4/9/98
- * @param
- * @return
- */
-CNavDTD::CNavDTD() : nsIDTD(),
- mMisplacedContent(0),
+CNavDTD::CNavDTD()
+ : mMisplacedContent(0),
mSink(0),
mTokenAllocator(0),
+ mBodyContext(new nsDTDContext()),
mTempContext(0),
- mParser(0),
+ mParser(0),
mTokenizer(0),
mDTDMode(eDTDMode_quirks),
mDocType(eHTML3_Quirks), // why not eHTML_Quirks?
@@ -183,54 +131,44 @@ CNavDTD::CNavDTD() : nsIDTD(),
mHeadContainerPosition(-1),
mFlags(NS_DTD_FLAG_NONE)
{
- mBodyContext=new nsDTDContext();
}
-/**
- *
- * @update gess1/8/99
- * @param
- * @return
- */
-const nsIID& CNavDTD::GetMostDerivedIID(void)const {
+const nsIID&
+CNavDTD::GetMostDerivedIID() const
+{
+ static nsIID kClassIID = NS_GET_IID(CNavDTD);
return kClassIID;
}
#ifdef NS_DEBUG
-nsLoggingSink* GetLoggingSink() {
+static nsLoggingSink*
+GetLoggingSink()
+{
+ // This returns a content sink that is useful for following what calls the DTD
+ // makes to the content sink.
- //these are used when you want to generate a log file for contentsink construction...
+ static PRBool checkForPath = PR_TRUE;
+ static nsLoggingSink *theSink = nsnull;
+ static const char* gLogPath = nsnull;
- static PRBool checkForPath=PR_TRUE;
- static nsLoggingSink *theSink=0;
- static const char* gLogPath=0;
-
- if(checkForPath) {
-
- // we're only going to check the environment once per session.
-
- gLogPath = /* "c:/temp/parse.log"; */ PR_GetEnv("PARSE_LOGFILE");
- checkForPath=PR_FALSE;
+ if (checkForPath) {
+ // Only check once per run.
+ gLogPath = PR_GetEnv("PARSE_LOGFILE");
+ checkForPath = PR_FALSE;
}
- if(gLogPath && (!theSink)) {
- static nsLoggingSink gLoggingSink;
+ if (gLogPath && !theSink) {
+ static nsLoggingSink gLoggingSink;
- PRIntn theFlags = 0;
+ PRIntn theFlags = PR_CREATE_FILE | PR_RDWR;
- // create the file exists, only open for read/write
- // otherwise, create it
- if(PR_Access(gLogPath,PR_ACCESS_EXISTS) != PR_SUCCESS)
- theFlags = PR_CREATE_FILE;
- theFlags |= PR_RDWR;
-
- // open the record file
- PRFileDesc *theLogFile = PR_Open(gLogPath,theFlags,0);
- gLoggingSink.SetOutputStream(theLogFile,PR_TRUE);
- theSink=&gLoggingSink;
+ // Open the record file.
+ PRFileDesc *theLogFile = PR_Open(gLogPath, theFlags, 0);
+ gLoggingSink.SetOutputStream(theLogFile, PR_TRUE);
+ theSink = &gLoggingSink;
}
return theSink;
@@ -238,29 +176,15 @@ nsLoggingSink* GetLoggingSink() {
#endif
-/**
- * Default destructor
- *
- * @update gess 4/9/98
- * @param
- * @return
- */
-CNavDTD::~CNavDTD(){
- if(mBodyContext) {
- delete mBodyContext;
- mBodyContext=0;
- }
+CNavDTD::~CNavDTD()
+{
+ delete mBodyContext;
+ delete mTempContext;
- if(mTempContext) {
- delete mTempContext;
- mTempContext=0;
- }
-
-
#ifdef NS_DEBUG
- if(mSink) {
- nsLoggingSink *theLogSink=GetLoggingSink();
- if(mSink==theLogSink) {
+ if (mSink) {
+ nsLoggingSink *theLogSink = GetLoggingSink();
+ if (mSink == theLogSink) {
theLogSink->ReleaseProxySink();
}
}
@@ -268,16 +192,9 @@ CNavDTD::~CNavDTD(){
NS_IF_RELEASE(mSink);
}
-
-/**
- * Call this method if you want the DTD to construct a fresh
- * instance of itself.
- * @update gess 25May2000
- * @param
- * @return
- */
-nsresult CNavDTD::CreateNewInstance(nsIDTD** aInstancePtrResult)
+nsresult
+CNavDTD::CreateNewInstance(nsIDTD** aInstancePtrResult)
{
nsresult result = NS_NewNavHTMLDTD(aInstancePtrResult);
NS_ENSURE_SUCCESS(result, result);
@@ -291,17 +208,6 @@ nsresult CNavDTD::CreateNewInstance(nsIDTD** aInstancePtrResult)
return result;
}
-/**
- * This method is called to determine if the given DTD can parse
- * a document in a given source-type.
- * NOTE: Parsing always assumes that the end result will involve
- * storing the result in the main content model.
- * @param aParserContext -- the context for this document (knows
- * the content type, document type, parser command, etc).
- * @return eUnknownDetect if you don't know how to parse it,
- * eValidDetect if you do, but someone may have a better idea,
- * ePrimaryDetect if you think you know best
- */
NS_IMETHODIMP_(eAutoDetectResult)
CNavDTD::CanParse(CParserContext& aParserContext)
{
@@ -322,22 +228,15 @@ CNavDTD::CanParse(CParserContext& aParserContext)
return eUnknownDetect;
}
-/**
- * The parser uses a code sandwich to wrap the parsing process. Before
- * the process begins, WillBuildModel() is called. Afterwards the parser
- * calls DidBuildModel().
- * @update rickg 03.20.2000
- * @param aParserContext
- * @param aSink
- * @return error code (almost always 0)
- */
-nsresult CNavDTD::WillBuildModel(const CParserContext& aParserContext,
- nsITokenizer* aTokenizer,
- nsIContentSink* aSink) {
- nsresult result=NS_OK;
+nsresult
+CNavDTD::WillBuildModel(const CParserContext& aParserContext,
+ nsITokenizer* aTokenizer,
+ nsIContentSink* aSink)
+{
+ nsresult result = NS_OK;
- mFilename=aParserContext.mScanner->GetFilename();
- mFlags = NS_DTD_FLAG_ENABLE_RESIDUAL_STYLE; // residual style is always on. This will also reset the flags
+ mFilename = aParserContext.mScanner->GetFilename();
+ mFlags = NS_DTD_FLAG_ENABLE_RESIDUAL_STYLE;
mLineNumber = 1;
mDTDMode = aParserContext.mDTDMode;
mParserCommand = aParserContext.mParserCommand;
@@ -346,8 +245,7 @@ nsresult CNavDTD::WillBuildModel(const CParserContext& aParserContext,
mTokenizer = aTokenizer;
mBodyContext->SetNodeAllocator(&mNodeAllocator);
- if(!aParserContext.mPrevContext && aSink) {
-
+ if (!aParserContext.mPrevContext && aSink) {
STOP_TIMER();
MOZ_TIMER_DEBUGLOG(("Stop: Parse Time: CNavDTD::WillBuildModel(), this=%p\n", this));
@@ -364,26 +262,26 @@ nsresult CNavDTD::WillBuildModel(const CParserContext& aParserContext,
}
}
- //let's see if the environment is set up for us to write output to
- //a logging sink. If so, then we'll create one, and make it the
- //proxy for the real sink we're given from the parser.
+ // Let's see if the environment is set up for us to write output to
+ // a logging sink. If so, then we'll create one, and make it the
+ // proxy for the real sink we're given from the parser.
#ifdef NS_DEBUG
- nsLoggingSink *theLogSink=GetLoggingSink();
- if(theLogSink) {
+ nsLoggingSink *theLogSink = GetLoggingSink();
+ if (theLogSink) {
theLogSink->SetProxySink(mSink);
- mSink=theLogSink;
+ mSink = theLogSink;
}
#endif
- if(mSink) {
+ if (mSink) {
PRBool enabled = PR_TRUE;
mSink->IsEnabled(eHTMLTag_frameset, &enabled);
- if(enabled) {
+ if (enabled) {
mFlags |= NS_IPARSER_FLAG_FRAMES_ENABLED;
}
mSink->IsEnabled(eHTMLTag_script, &enabled);
- if(enabled) {
+ if (enabled) {
mFlags |= NS_IPARSER_FLAG_SCRIPT_ENABLED;
}
}
@@ -392,114 +290,117 @@ nsresult CNavDTD::WillBuildModel(const CParserContext& aParserContext,
return result;
}
-
-/**
- * This is called when it's time to read as many tokens from the tokenizer
- * as you can. Not all tokens may make sense, so you may not be able to
- * read them all (until more come in later).
- *
- * @update gess5/18/98
- * @param aParser is the parser object that's driving this process
- * @return error code (almost always NS_OK)
- */
-nsresult CNavDTD::BuildModel(nsIParser* aParser,nsITokenizer* aTokenizer,nsITokenObserver* anObserver,nsIContentSink* aSink) {
- NS_PRECONDITION(mBodyContext!=nsnull,"Create a context before calling build model");
+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;
- if (aTokenizer && aParser) {
- nsITokenizer* oldTokenizer = mTokenizer;
+ if (!aTokenizer || !aParser) {
+ return NS_OK;
+ }
- mTokenizer = aTokenizer;
- mParser = (nsParser*)aParser;
- mTokenAllocator = mTokenizer->GetTokenAllocator();
-
- if (mSink) {
- 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);
- }
- }
+ nsITokenizer* oldTokenizer = mTokenizer;
- // always open a body if frames are disabled....
- if(!(mFlags & NS_IPARSER_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 ...
- theToken = (CStartToken*)mTokenizer->GetTokenAt(0);
- if (theToken) {
- eHTMLTags theTag = (eHTMLTags)theToken->GetTypeID();
- eHTMLTokenTypes theType = eHTMLTokenTypes(theToken->GetTokenType());
- if (theTag != eHTMLTag_html || theType != eToken_start) {
- 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.
- }
- }
- }
- else {
- 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.
- }
+ mTokenizer = aTokenizer;
+ mParser = (nsParser*)aParser;
+ mTokenAllocator = mTokenizer->GetTokenAllocator();
+
+ if (!mSink) {
+ return (mFlags & NS_DTD_FLAG_STOP_PARSING)
+ ? NS_ERROR_HTMLPARSER_STOPPARSING
+ : result;
+ }
+
+ if (mBodyContext->GetCount() == 0) {
+ CToken* tempToken;
+ if (ePlainText == mDocType) {
+ tempToken =
+ mTokenAllocator->CreateTokenOfType(eToken_start, eHTMLTag_pre);
+ if (tempToken) {
+ mTokenizer->PushTokenFront(tempToken);
+ }
+ }
+
+ // Always open a body if frames are disabled.
+ if (!(mFlags & NS_IPARSER_FLAG_FRAMES_ENABLED)) {
+ tempToken =
+ mTokenAllocator->CreateTokenOfType(eToken_start,
+ eHTMLTag_body,
+ NS_LITERAL_STRING("body"));
+ if (tempToken) {
+ mTokenizer->PushTokenFront(tempToken);
+ }
+ }
+
+ // If the content model is empty, then begin by opening .
+ CStartToken* theToken = (CStartToken*)mTokenizer->GetTokenAt(0);
+ if (theToken) {
+ eHTMLTags theTag = (eHTMLTags)theToken->GetTypeID();
+ eHTMLTokenTypes theType = eHTMLTokenTypes(theToken->GetTokenType());
+ if (theTag != eHTMLTag_html || theType != eToken_start) {
+ tempToken =
+ mTokenAllocator->CreateTokenOfType(eToken_start,
+ eHTMLTag_html,
+ NS_LITERAL_STRING("html"));
+ if (tempToken) {
+ mTokenizer->PushTokenFront(tempToken);
}
}
-
- 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 is processing a script's document.write we should not
- // allow it to be interrupted.
- // We also need to make sure that an interruption does not override
- // a request to block the parser.
- if (mParser->CanInterrupt() &&
- !IsParserInDocWrite() &&
- NS_SUCCEEDED(result)) {
- result = NS_ERROR_HTMLPARSER_INTERRUPTED;
- break;
- }
- }
- }//while
- mTokenizer = oldTokenizer;
- }
- else {
- result = mFlags & NS_DTD_FLAG_STOP_PARSING ? NS_ERROR_HTMLPARSER_STOPPARSING : result;
+ } else {
+ tempToken =
+ mTokenAllocator->CreateTokenOfType(eToken_start,
+ eHTMLTag_html,
+ NS_LITERAL_STRING("html"));
+ if (tempToken) {
+ mTokenizer->PushTokenFront(tempToken);
+ }
}
}
+ mSink->WillProcessTokens();
+
+ while (NS_SUCCEEDED(result)) {
+ if (!(mFlags & NS_DTD_FLAG_STOP_PARSING)) {
+ CToken* theToken = mTokenizer->PopToken();
+ if (!theToken) {
+ break;
+ }
+ result = HandleToken(theToken, aParser);
+ } 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 is processing a script's document.write we should not
+ // allow it to be interrupted.
+ // We also need to make sure that an interruption does not override
+ // a request to block the parser.
+ if (mParser->CanInterrupt() &&
+ !IsParserInDocWrite() &&
+ NS_SUCCEEDED(result)) {
+ result = NS_ERROR_HTMLPARSER_INTERRUPTED;
+ break;
+ }
+ }
+ }
+
+ mTokenizer = oldTokenizer;
return result;
}
-/**
- * @param aTarget - Tag that was neglected in the document.
- * @param aType - Specifies the type of the target. Ex. start, end, text, etc.
- * @param aParser - Parser to drive this process
- * @param aSink - HTML Content sink
- */
nsresult
CNavDTD::BuildNeglectedTarget(eHTMLTags aTarget,
eHTMLTokenTypes aType,
@@ -508,35 +409,35 @@ CNavDTD::BuildNeglectedTarget(eHTMLTags aTarget,
{
NS_ASSERTION(mTokenizer, "tokenizer is null! unable to build target.");
NS_ASSERTION(mTokenAllocator, "unable to create tokens without an allocator.");
- if (!mTokenizer || !mTokenAllocator)
+ if (!mTokenizer || !mTokenAllocator) {
return NS_OK;
- CHTMLToken* target =
- NS_STATIC_CAST(CHTMLToken*, mTokenAllocator->CreateTokenOfType(aType, aTarget));
+ }
+
+ CToken* target = mTokenAllocator->CreateTokenOfType(aType, aTarget);
mTokenizer->PushTokenFront(target);
return BuildModel(aParser, mTokenizer, 0, aSink);
}
-/**
- *
- * @update gess5/18/98
- * @param
- * @return
- */
-nsresult CNavDTD::DidBuildModel(nsresult anErrorCode,
- PRBool aNotifySink,
- nsIParser* aParser,
- nsIContentSink* aSink)
+nsresult
+CNavDTD::DidBuildModel(nsresult anErrorCode,
+ PRBool aNotifySink,
+ nsIParser* aParser,
+ nsIContentSink* aSink)
{
- if (!aSink)
+ if (!aSink) {
return NS_OK;
+ }
+
nsresult result = NS_OK;
- if (aParser && aNotifySink) {
+ if (aParser && aNotifySink) {
if (NS_OK == anErrorCode) {
if (!(mFlags & NS_DTD_FLAG_HAS_MAIN_CONTAINER)) {
// This document is not a frameset document, however, it did not contain
// a body tag either. So, make one!. Note: Body tag is optional per spec..
- result = BuildNeglectedTarget(eHTMLTag_body, eToken_start, aParser, aSink);
- NS_ENSURE_SUCCESS(result , result);
+ // Also note: We ignore the return value of BuildNeglectedTarget, we
+ // can't reasonably respond to errors (or requests to block) at this
+ // point in the parsing process.
+ BuildNeglectedTarget(eHTMLTag_body, eToken_start, aParser, aSink);
}
if (mFlags & NS_DTD_FLAG_MISPLACED_CONTENT) {
// Looks like the misplaced contents are not processed yet.
@@ -562,8 +463,10 @@ nsresult CNavDTD::DidBuildModel(nsresult anErrorCode,
} while (mFlags & NS_DTD_FLAG_MISPLACED_CONTENT);
mBodyContext->mContextTopIndex = -1;
- }
- //now let's disable style handling to save time when closing remaining stack members...
+ }
+
+ // Now let's disable style handling to save time when closing remaining
+ // stack members.
mFlags &= ~NS_DTD_FLAG_ENABLE_RESIDUAL_STYLE;
while (mBodyContext->GetCount() > 0) {
result = CloseContainersTo(mBodyContext->Last(), PR_FALSE);
@@ -573,28 +476,27 @@ nsresult CNavDTD::DidBuildModel(nsresult anErrorCode,
return result;
}
}
- }
- else {
- //If you're here, then an error occured, but we still have nodes on the stack.
- //At a minimum, we should grab the nodes and recycle them.
- //Just to be correct, we'll also recycle the nodes.
+ } else {
+ // If you're here, then an error occured, but we still have nodes on the stack.
+ // At a minimum, we should grab the nodes and recycle them.
+ // Just to be correct, we'll also recycle the nodes.
while (mBodyContext->GetCount() > 0) {
nsEntryStack* theChildStyles = 0;
nsCParserNode* theNode = mBodyContext->Pop(theChildStyles);
- IF_DELETE(theChildStyles,&mNodeAllocator);
+ IF_DELETE(theChildStyles, &mNodeAllocator);
IF_FREE(theNode, &mNodeAllocator);
}
}
- //Now make sure the misplaced content list is empty,
- //by forcefully recycling any tokens we might find there.
+ // Now make sure the misplaced content list is empty,
+ // by forcefully recycling any tokens we might find there.
CToken* theToken = 0;
while ((theToken = (CToken*)mMisplacedContent.Pop())) {
IF_FREE(theToken, mTokenAllocator);
}
- } //if aparser
+ }
- //No matter what, you need to call did build model.
+ // No matter what, you need to call did build model.
return aSink->DidBuildModel();
}
@@ -612,38 +514,41 @@ CNavDTD::GetType()
}
/**
- * --- Backwards compatibility ---
- * Use this method to determine if the tag in question needs a BODY.
- * ---
+ * Text and some tags require a body when they're added, this function returns
+ * true for those tags.
+ *
+ * @param aToken The current token that we care about.
+ * @param aTokenizer A tokenizer that we can get the tags attributes off of.
+ * @return PR_TRUE if aToken does indeed force the body to open.
*/
-static
-PRBool DoesRequireBody(CToken* aToken,nsITokenizer* aTokenizer) {
+static PRBool
+DoesRequireBody(CToken* aToken, nsITokenizer* aTokenizer)
+{
+ PRBool result = PR_FALSE;
- PRBool result=PR_FALSE;
-
- if(aToken) {
- eHTMLTags theTag=(eHTMLTags)aToken->GetTypeID();
- if(gHTMLElements[theTag].HasSpecialProperty(kRequiresBody)) {
- if(theTag==eHTMLTag_input) {
+ if (aToken) {
+ eHTMLTags theTag = (eHTMLTags)aToken->GetTypeID();
+ if (gHTMLElements[theTag].HasSpecialProperty(kRequiresBody)) {
+ if (theTag == eHTMLTag_input) {
// IE & Nav4x opens up a body for type=text - Bug 66985
- PRInt32 ac=aToken->GetAttributeCount();
- for(PRInt32 i=0; iGetTokenAt(i));
- const nsSubstring& name=attr->GetKey();
- const nsAString& value=attr->GetValue();
+ PRInt32 ac = aToken->GetAttributeCount();
+ for(PRInt32 i = 0; i < ac; ++i) {
+ CAttributeToken* attr = NS_STATIC_CAST(CAttributeToken*,
+ aTokenizer->GetTokenAt(i));
+ const nsSubstring& name = attr->GetKey();
+ const nsAString& value = attr->GetValue();
- if((name.EqualsLiteral("type") ||
- name.EqualsLiteral("TYPE"))
- &&
- !(value.EqualsLiteral("hidden") ||
- value.EqualsLiteral("HIDDEN"))) {
- result=PR_TRUE;
+ if ((name.EqualsLiteral("type") ||
+ name.EqualsLiteral("TYPE"))
+ &&
+ !(value.EqualsLiteral("hidden") ||
+ value.EqualsLiteral("HIDDEN"))) {
+ result = PR_TRUE;
break;
}
- }//for
- }
- else {
- result=PR_TRUE;
+ }
+ } else {
+ result = PR_TRUE;
}
}
}
@@ -654,8 +559,9 @@ PRBool DoesRequireBody(CToken* aToken,nsITokenizer* aTokenizer) {
/**
* Returns whether or not there is a tag of type aType open on aContext.
*/
-static
-PRBool HasOpenTagOfType(PRInt32 aType, const nsDTDContext& aContext) {
+static PRBool
+HasOpenTagOfType(PRInt32 aType, const nsDTDContext& aContext)
+{
PRInt32 count = aContext.GetCount();
while (--count >= 0) {
@@ -667,342 +573,312 @@ PRBool HasOpenTagOfType(PRInt32 aType, const nsDTDContext& aContext) {
return PR_FALSE;
}
-/**
- * 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
- * moved over to the delegate. Ah, so much to do...
- *
- * @update gess 12/1/99
- * @param aToken
- * @param aParser
- * @return
- */
-nsresult CNavDTD::HandleToken(CToken* aToken,nsIParser* aParser){
- nsresult result=NS_OK;
+nsresult
+CNavDTD::HandleToken(CToken* aToken, nsIParser* aParser)
+{
+ if (!aToken) {
+ return NS_OK;
+ }
- if(aToken) {
- CHTMLToken* theToken= NS_STATIC_CAST(CHTMLToken*, aToken);
- eHTMLTokenTypes theType=eHTMLTokenTypes(theToken->GetTokenType());
- eHTMLTags theTag=(eHTMLTags)theToken->GetTypeID();
+ nsresult result = NS_OK;
+ CHTMLToken* theToken = NS_STATIC_CAST(CHTMLToken*, aToken);
+ eHTMLTokenTypes theType = eHTMLTokenTypes(theToken->GetTokenType());
+ eHTMLTags theTag = (eHTMLTags)theToken->GetTypeID();
- aToken->SetLineNumber(mLineNumber);
+ aToken->SetLineNumber(mLineNumber);
- if (!IsParserInDocWrite()) {
- mLineNumber += aToken->GetNewlineCount();
+ if (!IsParserInDocWrite()) {
+ mLineNumber += aToken->GetNewlineCount();
+ }
+
+ if (mFlags & NS_DTD_FLAG_MISPLACED_CONTENT) {
+ // Included TD & TH to fix Bug# 20797
+ static eHTMLTags gLegalElements[] = {
+ eHTMLTag_table, eHTMLTag_thead, eHTMLTag_tbody,
+ eHTMLTag_tr, eHTMLTag_td, eHTMLTag_th, eHTMLTag_tfoot
+ };
+ // Don't even try processing misplaced tokens if we're already
+ // handling misplaced content. See bug 269095
+ if (mFlags & NS_DTD_FLAG_IN_MISPLACED_CONTENT) {
+ PushIntoMisplacedStack(theToken);
+ return NS_OK;
}
-
- if(mFlags & NS_DTD_FLAG_MISPLACED_CONTENT) {
- // Included TD & TH to fix Bug# 20797
- static eHTMLTags gLegalElements[]={eHTMLTag_table,eHTMLTag_thead,eHTMLTag_tbody,
- eHTMLTag_tr,eHTMLTag_td,eHTMLTag_th,eHTMLTag_tfoot};
- if(theToken) {
- // Don't even try processing misplaced tokens if we're already
- // handling misplaced content. See bug 269095
- if (mFlags & NS_DTD_FLAG_IN_MISPLACED_CONTENT) {
- PushIntoMisplacedStack(theToken);
- return result;
- }
- eHTMLTags theParentTag=mBodyContext->Last();
- theTag=(eHTMLTags)theToken->GetTypeID();
- if(FindTagInSet(theTag, gLegalElements,
- NS_ARRAY_LENGTH(gLegalElements)) ||
- (gHTMLElements[theParentTag].CanContain(theTag,mDTDMode) &&
- // Here's a problem. If theTag is legal in here, we don't move it
- // out. So if we're moving stuff out of here, the parent of theTag
- // gets closed at this point. But some things are legal
- // _everywhere_ and hence would effectively close out misplaced
- // content in tables. This is undesirable, so treat them as
- // illegal here so they'll be shipped out with their parents and
- // siblings. See bug 40855 for an explanation (that bug was for
- // comments, but the same issues arise with whitespace, newlines,
- // noscript, etc). Script is special, though. Shipping it out
- // breaks document.write stuff. See bug 243064.
- (!gHTMLElements[theTag].HasSpecialProperty(kLegalOpen) ||
- theTag == eHTMLTag_script))) {
-
- mFlags &= ~NS_DTD_FLAG_MISPLACED_CONTENT; // reset the state since all the misplaced tokens are about to get handled.
+ eHTMLTags theParentTag = mBodyContext->Last();
+ theTag = (eHTMLTags)theToken->GetTypeID();
+ if (FindTagInSet(theTag, gLegalElements,
+ NS_ARRAY_LENGTH(gLegalElements)) ||
+ (gHTMLElements[theParentTag].CanContain(theTag, mDTDMode) &&
+ // Here's a problem. If theTag is legal in here, we don't move it
+ // out. So if we're moving stuff out of here, the parent of theTag
+ // gets closed at this point. But some things are legal
+ // _everywhere_ and hence would effectively close out misplaced
+ // content in tables. This is undesirable, so treat them as
+ // illegal here so they'll be shipped out with their parents and
+ // siblings. See bug 40855 for an explanation (that bug was for
+ // comments, but the same issues arise with whitespace, newlines,
+ // noscript, etc). Script is special, though. Shipping it out
+ // breaks document.write stuff. See bug 243064.
+ (!gHTMLElements[theTag].HasSpecialProperty(kLegalOpen) ||
+ theTag == eHTMLTag_script))) {
+ // Reset the state since all the misplaced tokens are about to get
+ // handled.
+ mFlags &= ~NS_DTD_FLAG_MISPLACED_CONTENT;
- result = HandleSavedTokens(mBodyContext->mContextTopIndex);
- NS_ENSURE_SUCCESS(result, result);
+ result = HandleSavedTokens(mBodyContext->mContextTopIndex);
+ NS_ENSURE_SUCCESS(result, result);
- mBodyContext->mContextTopIndex = -1;
- }
- else {
- PushIntoMisplacedStack(theToken);
- return result;
+ mBodyContext->mContextTopIndex = -1;
+ } else {
+ PushIntoMisplacedStack(theToken);
+ return result;
+ }
+ }
+
+ /*
+ * This section of code is used to "move" misplaced content from one location
+ * in our document model to another. (Consider what would happen if we found a
+ *
tag in the head.) To move content, we throw it onto the
+ * misplacedcontent deque until we can deal with it.
+ */
+ switch(theTag) {
+ case eHTMLTag_html:
+ case eHTMLTag_noframes:
+ case eHTMLTag_noscript:
+ case eHTMLTag_script:
+ case eHTMLTag_doctypeDecl:
+ case eHTMLTag_instruction:
+ break;
+
+ default:
+ if (!gHTMLElements[eHTMLTag_html].SectionContains(theTag, PR_FALSE)) {
+ if (!(mFlags & (NS_DTD_FLAG_HAS_MAIN_CONTAINER |
+ NS_DTD_FLAG_ALTERNATE_CONTENT))) {
+ // For bug examples from this code, see bugs: 18928, 20989.
+ // At this point we know the body/frameset aren't open.
+ // If the child belongs in the head, then handle it (which may open the head);
+ // otherwise, push it onto the misplaced stack.
+
+ PRBool isExclusive = PR_FALSE;
+ PRBool theChildBelongsInHead =
+ gHTMLElements[eHTMLTag_head].IsChildOfHead(theTag, isExclusive);
+ if (theChildBelongsInHead && !isExclusive) {
+ if (mMisplacedContent.GetSize() == 0) {
+ // This tag can either be in the body or the head. Since
+ // there is no indication that the body should be open,
+ // put this token in the head.
+ break;
+ }
+
+ // Otherwise, we have received some indication that the body is
+ // "open", so push this token onto the misplaced content stack.
+ theChildBelongsInHead = PR_FALSE;
+ }
+
+ if (!theChildBelongsInHead) {
+ eHTMLTags top = mBodyContext->Last();
+ NS_ASSERTION(top != eHTMLTag_userdefined,
+ "Userdefined tags should act as leaves in the head");
+ if (top != eHTMLTag_html &&
+ gHTMLElements[top].CanContain(theTag, mDTDMode)) {
+ // Some tags (such as