Bug 903912 - Remove the internals of the old parser since it's only used for about:blank. r=hsivonen

--HG--
extra : rebase_source : 620d34c12607f1e79ffed95e547d19e9c7a2359b
This commit is contained in:
Blake Kaplan 2013-08-12 11:28:41 -04:00
parent 3aed4aaa4c
commit 5c3a529f78
28 changed files with 653 additions and 12026 deletions

View File

@ -25,7 +25,7 @@
#include "nsIContentViewer.h"
#include "nsIMarkupDocumentViewer.h"
#include "nsINodeInfo.h"
#include "nsHTMLTokens.h"
#include "nsToken.h"
#include "nsIAppShell.h"
#include "nsCRT.h"
#include "prtime.h"
@ -430,14 +430,8 @@ HTMLContentSink::CreateContentObject(const nsIParserNode& aNode,
nsCOMPtr<nsINodeInfo> nodeInfo;
if (aNodeType == eHTMLTag_userdefined) {
nsAutoString lower;
nsContentUtils::ASCIIToLower(aNode.GetText(), lower);
nsCOMPtr<nsIAtom> name = do_GetAtom(lower);
nodeInfo = mNodeInfoManager->GetNodeInfo(name, nullptr, kNameSpaceID_XHTML,
nsIDOMNode::ELEMENT_NODE);
}
else if (mNodeInfoCache[aNodeType]) {
MOZ_ASSERT(aNodeType != eHTMLTag_userdefined);
if (mNodeInfoCache[aNodeType]) {
nodeInfo = mNodeInfoCache[aNodeType];
}
else {
@ -864,25 +858,11 @@ SinkContext::AddLeaf(const nsIParserNode& aNode)
case eToken_text:
case eToken_whitespace:
case eToken_newline:
rv = AddText(aNode.GetText());
MOZ_CRASH();
break;
case eToken_entity:
{
nsAutoString tmp;
int32_t unicode = aNode.TranslateToUnicodeStr(tmp);
if (unicode < 0) {
rv = AddText(aNode.GetText());
} else {
// Map carriage returns to newlines
if (!tmp.IsEmpty()) {
if (tmp.CharAt(0) == '\r') {
tmp.Assign((PRUnichar)'\n');
}
rv = AddText(tmp);
}
}
}
MOZ_CRASH();
break;
default:

View File

@ -11,7 +11,6 @@
#include "nsIDOMNode.h"
#include "nsGkAtoms.h"
#include "nsINameSpaceManager.h"
#include "nsHTMLTokens.h"
#include "nsIURI.h"
#include "nsTextFragment.h"
#ifdef MOZ_XUL

View File

@ -14,7 +14,6 @@ MODULE = 'htmlparser'
EXPORTS += [
'nsHTMLTagList.h',
'nsHTMLTags.h',
'nsHTMLTokens.h',
'nsIContentSink.h',
'nsIDTD.h',
'nsIElementObserver.h',

View File

@ -1,376 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/**
* MODULE NOTES:
* @update gess 4/1/98
*
* This file contains the declarations for all the HTML specific token types that
* our DTD's understand. In fact, the same set of token types are used for XML.
* Currently we have tokens for text, comments, start and end tags, entities,
* attributes, style, script and skipped content. Whitespace and newlines also
* have their own token types, but don't count on them to stay forever.
*
* If you're looking for the html tags, they're in a file called nsHTMLTag.h/cpp.
*
* Most of the token types have a similar API. They have methods to get the type
* of token (GetTokenType); those that represent HTML tags also have a method to
* get type tag type (GetTypeID). In addition, most have a method that causes the
* token to help in the parsing process called (Consume). We've also thrown in a
* few standard debugging methods as well.
*/
#ifndef HTMLTOKENS_H
#define HTMLTOKENS_H
#include "nsToken.h"
#include "nsHTMLTags.h"
#include "nsString.h"
#include "nsScannerString.h"
class nsScanner;
/*******************************************************************
* This enum defines the set of token types that we currently support.
*******************************************************************/
enum eHTMLTokenTypes {
eToken_unknown=0,
eToken_start=1, eToken_end, eToken_comment, eToken_entity,
eToken_whitespace, eToken_newline, eToken_text, eToken_attribute,
eToken_instruction, eToken_cdatasection, eToken_doctypeDecl, eToken_markupDecl,
eToken_last //make sure this stays the last token...
};
nsresult ConsumeQuotedString(PRUnichar aChar,nsString& aString,nsScanner& aScanner);
nsresult ConsumeAttributeText(PRUnichar aChar,nsString& aString,nsScanner& aScanner);
const PRUnichar* GetTagName(int32_t aTag);
//int32_t FindEntityIndex(nsString& aString,int32_t aCount=-1);
/**
* This declares the basic token type used in the HTML DTD's.
* @update gess 3/25/98
*/
class CHTMLToken : public CToken {
public:
virtual ~CHTMLToken();
CHTMLToken(eHTMLTags aTag);
virtual eContainerInfo GetContainerInfo(void) const {return eFormUnknown;}
virtual void SetContainerInfo(eContainerInfo aInfo) { }
protected:
};
/**
* This declares start tokens, which always take the form <xxxx>.
* This class also knows how to consume related attributes.
*
* @update gess 3/25/98
*/
class CStartToken: public CHTMLToken {
public:
CStartToken(eHTMLTags aTag=eHTMLTag_unknown);
CStartToken(const nsAString& aString);
CStartToken(const nsAString& aName,eHTMLTags aTag);
virtual nsresult Consume(PRUnichar aChar,nsScanner& aScanner,int32_t aMode);
virtual int32_t GetTypeID(void);
virtual int32_t GetTokenType(void);
virtual bool IsEmpty(void);
virtual void SetEmpty(bool aValue);
virtual const nsSubstring& GetStringValue();
virtual void GetSource(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;}
virtual void SetContainerInfo(eContainerInfo aContainerInfo) {
if (eFormUnknown==mContainerInfo) {
mContainerInfo=aContainerInfo;
}
}
virtual bool IsWellFormed(void) const {
return eWellFormed == mContainerInfo;
}
nsString mTextValue;
protected:
eContainerInfo mContainerInfo;
bool mEmpty;
#ifdef DEBUG
bool mAttributed;
#endif
};
/**
* This declares end tokens, which always take the
* form </xxxx>. This class also knows how to consume
* related attributes.
*
* @update gess 3/25/98
*/
class CEndToken: public CHTMLToken {
public:
CEndToken(eHTMLTags aTag);
CEndToken(const nsAString& aString);
CEndToken(const nsAString& aName,eHTMLTags aTag);
virtual nsresult Consume(PRUnichar aChar,nsScanner& aScanner,int32_t aMode);
virtual int32_t GetTypeID(void);
virtual int32_t GetTokenType(void);
virtual const nsSubstring& GetStringValue();
virtual void GetSource(nsString& anOutputString);
virtual void AppendSourceTo(nsAString& anOutputString);
protected:
nsString mTextValue;
};
/**
* This declares comment tokens. Comments are usually
* thought of as tokens, but we treat them that way
* here so that the parser can have a consistent view
* of all tokens.
*
* @update gess 3/25/98
*/
class CCommentToken: public CHTMLToken {
public:
CCommentToken();
CCommentToken(const nsAString& aString);
virtual nsresult Consume(PRUnichar aChar,nsScanner& aScanner,int32_t aMode);
virtual int32_t GetTokenType(void);
virtual const nsSubstring& GetStringValue(void);
virtual void AppendSourceTo(nsAString& anOutputString);
nsresult ConsumeStrictComment(nsScanner& aScanner);
nsresult ConsumeQuirksComment(nsScanner& aScanner);
protected:
nsScannerSubstring mComment; // does not include MDO & MDC
nsScannerSubstring mCommentDecl; // includes MDO & MDC
};
/**
* This class declares entity tokens, which always take
* the form &xxxx;. This class also offers a few utility
* methods that allow you to easily reduce entities.
*
* @update gess 3/25/98
*/
class CEntityToken : public CHTMLToken {
public:
CEntityToken();
CEntityToken(const nsAString& aString);
virtual int32_t GetTokenType(void);
int32_t TranslateToUnicodeStr(nsString& aString);
virtual nsresult Consume(PRUnichar aChar,nsScanner& aScanner,int32_t aMode);
static nsresult ConsumeEntity(PRUnichar aChar, nsString& aString,
nsScanner& aScanner);
static int32_t TranslateToUnicodeStr(int32_t aValue,nsString& aString);
virtual const nsSubstring& GetStringValue(void);
virtual void GetSource(nsString& anOutputString);
virtual void AppendSourceTo(nsAString& anOutputString);
protected:
nsString mTextValue;
};
/**
* Whitespace tokens are used where whitespace can be
* detected as distinct from text. This allows us to
* easily skip leading/trailing whitespace when desired.
*
* @update gess 3/25/98
*/
class CWhitespaceToken: public CHTMLToken {
public:
CWhitespaceToken();
CWhitespaceToken(const nsAString& aString);
virtual nsresult Consume(PRUnichar aChar,nsScanner& aScanner,int32_t aMode);
virtual int32_t GetTokenType(void);
virtual const nsSubstring& GetStringValue(void);
protected:
nsScannerSharedSubstring mTextValue;
};
/**
* Text tokens contain the normalized form of html text.
* These tokens are guaranteed not to contain entities,
* start or end tags, or newlines.
*
* @update gess 3/25/98
*/
class CTextToken: public CHTMLToken {
public:
CTextToken();
CTextToken(const nsAString& aString);
virtual nsresult Consume(PRUnichar aChar,nsScanner& aScanner,int32_t aMode);
virtual int32_t GetTokenType(void);
virtual int32_t GetTextLength(void);
virtual void CopyTo(nsAString& aStr);
virtual const nsSubstring& GetStringValue(void);
virtual void Bind(nsScanner* aScanner, nsScannerIterator& aStart,
nsScannerIterator& aEnd);
virtual void Bind(const nsAString& aStr);
nsresult ConsumeCharacterData(bool aIgnoreComments,
nsScanner& aScanner,
const nsAString& aEndTagName,
int32_t aFlag,
bool& aFlushTokens);
nsresult ConsumeParsedCharacterData(bool aDiscardFirstNewline,
bool aConservativeConsume,
nsScanner& aScanner,
const nsAString& aEndTagName,
int32_t aFlag,
bool& aFound);
protected:
nsScannerSubstring mTextValue;
};
/**
* CDATASection tokens contain raw unescaped text content delimited by
* a ![CDATA[ and ]].
* XXX Not really a HTML construct - maybe we need a separation
*
* @update vidur 11/12/98
*/
class CCDATASectionToken : public CHTMLToken {
public:
CCDATASectionToken(eHTMLTags aTag = eHTMLTag_unknown);
CCDATASectionToken(const nsAString& aString);
virtual nsresult Consume(PRUnichar aChar,nsScanner& aScanner,int32_t aMode);
virtual int32_t GetTokenType(void);
virtual const nsSubstring& GetStringValue(void);
protected:
nsString mTextValue;
};
/**
* Declaration tokens contain raw unescaped text content (not really, but
* right now we use this only for view source).
* XXX Not really a HTML construct - maybe we need a separation
*
*/
class CMarkupDeclToken : public CHTMLToken {
public:
CMarkupDeclToken();
CMarkupDeclToken(const nsAString& aString);
virtual nsresult Consume(PRUnichar aChar,nsScanner& aScanner,int32_t aMode);
virtual int32_t GetTokenType(void);
virtual const nsSubstring& GetStringValue(void);
protected:
nsScannerSubstring mTextValue;
};
/**
* Attribute tokens are used to contain attribute key/value
* pairs whereever they may occur. Typically, they should
* occur only in start tokens. However, we may expand that
* ability when XML tokens become commonplace.
*
* @update gess 3/25/98
*/
class CAttributeToken: public CHTMLToken {
public:
CAttributeToken();
CAttributeToken(const nsAString& aString);
CAttributeToken(const nsAString& aKey, const nsAString& aString);
~CAttributeToken() {}
virtual nsresult Consume(PRUnichar aChar,nsScanner& aScanner,int32_t aMode);
virtual int32_t GetTokenType(void);
const nsSubstring& GetKey(void) { return mTextKey.AsString(); }
virtual void SetKey(const nsAString& aKey);
virtual void BindKey(nsScanner* aScanner, nsScannerIterator& aStart,
nsScannerIterator& aEnd);
const nsSubstring& GetValue(void) {return mTextValue.str();}
virtual const nsSubstring& GetStringValue(void);
virtual void GetSource(nsString& anOutputString);
virtual void AppendSourceTo(nsAString& anOutputString);
bool mHasEqualWithoutValue;
protected:
nsScannerSharedSubstring mTextValue;
nsScannerSubstring mTextKey;
};
/**
* Newline tokens contain, you guessed it, newlines.
* They consume newline (CR/LF) either alone or in pairs.
*
* @update gess 3/25/98
*/
class CNewlineToken: public CHTMLToken {
public:
CNewlineToken();
virtual nsresult Consume(PRUnichar aChar,nsScanner& aScanner,int32_t aMode);
virtual int32_t GetTokenType(void);
virtual const nsSubstring& GetStringValue(void);
static void AllocNewline();
static void FreeNewline();
};
/**
* Whitespace tokens are used where whitespace can be
* detected as distinct from text. This allows us to
* easily skip leading/trailing whitespace when desired.
*
* @update gess 3/25/98
*/
class CInstructionToken: public CHTMLToken {
public:
CInstructionToken();
CInstructionToken(const nsAString& aString);
virtual nsresult Consume(PRUnichar aChar,nsScanner& aScanner,int32_t aMode);
virtual int32_t GetTokenType(void);
virtual const nsSubstring& GetStringValue(void);
protected:
nsString mTextValue;
};
/**
* This token is generated by the HTML and Expat tokenizers
* when they see the doctype declaration ("<!DOCTYPE ... >")
*
*/
class CDoctypeDeclToken: public CHTMLToken {
public:
CDoctypeDeclToken(eHTMLTags aTag=eHTMLTag_unknown);
CDoctypeDeclToken(const nsAString& aString,eHTMLTags aTag=eHTMLTag_unknown);
virtual nsresult Consume(PRUnichar aChar,nsScanner& aScanner,int32_t aMode);
virtual int32_t GetTokenType(void);
virtual const nsSubstring& GetStringValue(void);
virtual void SetStringValue(const nsAString& aStr);
protected:
nsString mTextValue;
};
#endif

View File

@ -47,7 +47,6 @@ enum nsDTDMode {
class nsIParser;
class CToken;
class nsIURI;
class nsIContentSink;
class CParserContext;
@ -81,9 +80,7 @@ public:
* that the DTD should use (pointer in case the DTD
* opts to ignore this parameter)
*/
NS_IMETHOD BuildModel(nsITokenizer* aTokenizer,
bool aCountLines,
const nsCString* aCharsetPtr) = 0;
NS_IMETHOD BuildModel(nsITokenizer* aTokenizer, nsIContentSink* aSink) = 0;
/**
* This method is called to determine whether or not a tag of one
@ -132,7 +129,7 @@ NS_DEFINE_STATIC_IID_ACCESSOR(nsIDTD, NS_IDTD_IID)
#define NS_DECL_NSIDTD \
NS_IMETHOD WillBuildModel( const CParserContext& aParserContext, nsITokenizer* aTokenizer, nsIContentSink* aSink);\
NS_IMETHOD DidBuildModel(nsresult anErrorCode);\
NS_IMETHOD BuildModel(nsITokenizer* aTokenizer, bool aCountLines, const nsCString* aCharsetPtr);\
NS_IMETHOD BuildModel(nsITokenizer* aTokenizer, nsIContentSink* aSink);\
NS_IMETHOD_(bool) CanContain(int32_t aParent,int32_t aChild) const;\
NS_IMETHOD_(bool) IsContainer(int32_t aTag) const;\
NS_IMETHOD_(void) Terminate();\

View File

@ -23,20 +23,9 @@
#ifndef NS_IPARSERNODE__
#define NS_IPARSERNODE__
#include "nsISupports.h"
#include "nsStringGlue.h"
#include "nsDebug.h"
//#define HEAP_ALLOCATED_NODES
//#define DEBUG_TRACK_NODES
class nsIAtom;
class CToken;
// 6e59f160-2717-11d2-9246-00805f8a7ab6
#define NS_IPARSER_NODE_IID \
{0x6e59f160, 0x2717, 0x11d1, \
{0x92, 0x46, 0x00, 0x80, 0x5f, 0x8a, 0x7a, 0xb6}}
/**
* Parser nodes are the unit of exchange between the
@ -46,25 +35,8 @@ class CToken;
*
* @update gess 3/25/98
*/
class nsIParserNode { // XXX Should be nsAParserNode
class nsIParserNode {
public:
/**
* Retrieve the name of the node
* @update gess5/11/98
* @return string containing node name
*/
virtual const nsAString& GetTagName() const = 0; //to get name of tag
/**
* Retrieve the text from the given node
* @update gess5/11/98
* @return string containing node text
*/
virtual const nsAString& GetText() const = 0; //get plain text if available
/**
* Retrieve the type of the parser node.
* @update gess5/11/98
@ -84,7 +56,7 @@ class nsIParserNode { // XXX Should be nsAParserNode
* @update gess5/11/98
* @return count of attributes (may be 0)
*/
virtual int32_t GetAttributeCount(bool askToken=false) const =0;
virtual int32_t GetAttributeCount() const =0;
/**
* Retrieve the key (of key/value pair) at given index
@ -101,46 +73,6 @@ class nsIParserNode { // XXX Should be nsAParserNode
* @return string containing value.
*/
virtual const nsAString& GetValueAt(uint32_t anIndex) const = 0;
/**
* NOTE: When the node is an entity, this will translate the entity
* to it's unicode value, and store it in aString.
* @update gess5/11/98
* @param aString will contain the resulting unicode string value
* @return int (unicode char or unicode index from table)
*/
virtual int32_t TranslateToUnicodeStr(nsString& aString) const = 0;
virtual void AddAttribute(CToken* aToken)=0;
/**
* This getter retrieves the line number from the input source where
* the token occurred. Lines are interpreted as occurring between \n characters.
* @update gess7/24/98
* @return int containing the line number the token was found on
*/
virtual int32_t GetSourceLineNumber(void) const =0;
/**
* This pair of methods allows us to set a generic bit (for arbitrary use)
* on each node stored in the context.
* @update gess 11May2000
*/
virtual bool GetGenericState(void) const =0;
virtual void SetGenericState(bool aState) =0;
/** Retrieve a string containing the tag and its attributes in "source" form
* @update rickg 06June2000
* @return void
*/
virtual void GetSource(nsString& aString) const = 0;
/** Release all the objects you're holding
* @update harishd 08/02/00
* @return void
*/
virtual nsresult ReleaseAll()=0;
};
#endif

View File

@ -15,14 +15,11 @@
#include "nsISupports.h"
class CToken;
class nsScanner;
class nsDeque;
class nsTokenAllocator;
#define NS_ITOKENIZER_IID \
{0xe4238ddc, 0x9eb6, 0x11d2, {0xba, 0xa5, 0x0, 0x10, 0x4b, 0x98, 0x3f, 0xd4 }}
{ 0Xae98a348, 0X5e91, 0X41a8, \
{ 0Xa5, 0Xb4, 0Xd2, 0X20, 0Xf3, 0X1f, 0Xc4, 0Xab } }
/***************************************************************
Notes:
@ -33,37 +30,15 @@ class nsITokenizer : public nsISupports {
public:
NS_DECLARE_STATIC_IID_ACCESSOR(NS_ITOKENIZER_IID)
NS_IMETHOD WillTokenize(bool aIsFinalChunk,nsTokenAllocator* aTokenAllocator)=0;
NS_IMETHOD WillTokenize(bool aIsFinalChunk)=0;
NS_IMETHOD ConsumeToken(nsScanner& aScanner,bool& aFlushTokens)=0;
NS_IMETHOD DidTokenize(bool aIsFinalChunk)=0;
NS_IMETHOD_(CToken*) PushTokenFront(CToken* aToken)=0;
NS_IMETHOD_(CToken*) PushToken(CToken* aToken)=0;
NS_IMETHOD_(CToken*) PopToken(void)=0;
NS_IMETHOD_(CToken*) PeekToken(void)=0;
NS_IMETHOD_(CToken*) GetTokenAt(int32_t anIndex)=0;
NS_IMETHOD_(int32_t) GetCount(void)=0;
NS_IMETHOD_(nsTokenAllocator*) GetTokenAllocator(void)=0;
NS_IMETHOD_(void) PrependTokens(nsDeque& aDeque)=0;
NS_IMETHOD CopyState(nsITokenizer* aTokenizer)=0;
};
NS_DEFINE_STATIC_IID_ACCESSOR(nsITokenizer, NS_ITOKENIZER_IID)
#define NS_DECL_NSITOKENIZER \
NS_IMETHOD WillTokenize(bool aIsFinalChunk,nsTokenAllocator* aTokenAllocator);\
NS_IMETHOD WillTokenize(bool aIsFinalChunk);\
NS_IMETHOD ConsumeToken(nsScanner& aScanner,bool& aFlushTokens);\
NS_IMETHOD DidTokenize(bool aIsFinalChunk);\
NS_IMETHOD_(CToken*) PushTokenFront(CToken* aToken);\
NS_IMETHOD_(CToken*) PushToken(CToken* aToken);\
NS_IMETHOD_(CToken*) PopToken(void);\
NS_IMETHOD_(CToken*) PeekToken(void);\
NS_IMETHOD_(CToken*) GetTokenAt(int32_t anIndex);\
NS_IMETHOD_(int32_t) GetCount(void);\
NS_IMETHOD_(nsTokenAllocator*) GetTokenAllocator(void);\
NS_IMETHOD_(void) PrependTokens(nsDeque& aDeque);\
NS_IMETHOD CopyState(nsITokenizer* aTokenizer);
#endif

View File

@ -3,27 +3,6 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/**
* MODULE NOTES:
* @update gess 4/1/98
*
* This class is defines the basic notion of a token
* within our system. All other tokens are derived from
* this one. It offers a few basic interfaces, but the
* most important is consume(). The consume() method gets
* called during the tokenization process when an instance
* of that particular token type gets detected in the
* input stream.
*
* CToken objects that are allocated from the heap are allocated
* using the nsTokenAllocator object. nsTokenAllocator used to use
* an arena-style allocator, but that is no longer necessary or helpful;
* it now uses a trivial drop-in replacement for the arena-style
* allocator called nsDummyAllocator, which just wraps malloc/free.
*/
#ifndef CTOKEN__
#define CTOKEN__
@ -34,230 +13,14 @@
class nsScanner;
class nsTokenAllocator;
/**
* A trivial allocator. See the comment at the top of this file.
*/
class nsDummyAllocator {
public:
void* Alloc(size_t aSize) { return malloc(aSize); }
void Free(void* aPtr) { free(aPtr); }
enum eHTMLTokenTypes {
eToken_unknown=0,
eToken_start=1, eToken_end, eToken_comment, eToken_entity,
eToken_whitespace, eToken_newline, eToken_text, eToken_attribute,
eToken_instruction, eToken_cdatasection, eToken_doctypeDecl, eToken_markupDecl,
eToken_last //make sure this stays the last token...
};
enum eContainerInfo {
eWellFormed,
eMalformed,
eFormUnknown
};
/**
* Token objects represent sequences of characters as they
* are consumed from the input stream (URL). While they're
* pretty general in nature, we use subclasses (found in
* nsHTMLTokens.h) to define <start>, </end>, <text>,
* <comment>, <&entity>, <newline>, and <whitespace> tokens.
*
* @update gess 3/25/98
*/
class CToken {
public:
enum eTokenOrigin {eSource,eResidualStyle};
protected:
// nsTokenAllocator should be the only class that tries to
// allocate tokens from the heap.
friend class nsTokenAllocator;
/**
*
* @update harishd 08/01/00
* @param aSize -
* @param aArena - Allocate memory from this pool.
*/
static void * operator new (size_t aSize, nsDummyAllocator& anArena) CPP_THROW_NEW
{
return anArena.Alloc(aSize);
}
/**
* Hide operator delete; clients should use Destroy() instead.
*/
static void operator delete (void*,size_t) {}
protected:
/**
* destructor
* @update gess5/11/98
*/
virtual ~CToken();
private:
/**
* Destroy a token.
*/
static void Destroy(CToken* aToken, nsDummyAllocator& aArenaPool)
{
aToken->~CToken();
aArenaPool.Free(aToken);
}
public:
/**
* Make a note on number of times you have been referenced
* @update harishd 08/02/00
*/
void AddRef() {
++mUseCount;
NS_LOG_ADDREF(this, mUseCount, "CToken", sizeof(*this));
}
/**
* Free yourself if no one is holding you.
* @update harishd 08/02/00
*/
void Release(nsDummyAllocator& aArenaPool) {
--mUseCount;
NS_LOG_RELEASE(this, mUseCount, "CToken");
if (mUseCount==0)
Destroy(this, aArenaPool);
}
/**
* Default constructor
* @update gess7/21/98
*/
CToken(int32_t aTag=0);
/**
* Retrieve string value of the token
* @update gess5/11/98
* @return reference to string containing string value
*/
virtual const nsSubstring& GetStringValue(void) = 0;
/**
* Get string of full contents, suitable for debug dump.
* It should look exactly like the input source.
* @update gess5/11/98
* @return reference to string containing string value
*/
virtual void GetSource(nsString& anOutputString);
/** @update harishd 03/23/00
* @return reference to string containing string value
*/
virtual void AppendSourceTo(nsAString& anOutputString);
/**
* Sets the ordinal value of this token (not currently used)
* @update gess5/11/98
* @param value is the new ord value for this token
*/
void SetTypeID(int32_t aValue) {
mTypeID = aValue;
}
/**
* Getter which retrieves the current ordinal value for this token
* @update gess5/11/98
* @return current ordinal value
*/
virtual int32_t GetTypeID(void);
/**
* Getter which retrieves the current attribute count for this token
* @update gess5/11/98
* @return current attribute count
*/
virtual int16_t GetAttributeCount(void);
/**
* Causes token to consume data from given scanner.
* Note that behavior varies wildly between CToken subclasses.
* @update gess5/11/98
* @param aChar -- most recent char consumed
* @param aScanner -- input source where token should get data
* @return error code (0 means ok)
*/
virtual nsresult Consume(PRUnichar aChar,nsScanner& aScanner,int32_t aMode);
/**
* Getter which retrieves type of token
* @update gess5/11/98
* @return int containing token type
*/
virtual int32_t GetTokenType(void);
/**
* For tokens who care, this can tell us whether the token is
* well formed or not.
*
* @update gess 8/30/00
* @return false; subclasses MUST override if they care.
*/
virtual bool IsWellFormed(void) const {return false;}
virtual bool IsEmpty(void) { return false; }
/**
* If aValue is TRUE then the token represents a short-hand tag
*/
virtual void SetEmpty(bool aValue) { return ; }
int32_t GetNewlineCount()
{
return mNewlineCount;
}
void SetNewlineCount(int32_t aCount)
{
mNewlineCount = aCount;
}
int32_t GetLineNumber()
{
return mLineNumber;
}
void SetLineNumber(int32_t aLineNumber)
{
mLineNumber = mLineNumber == 0 ? aLineNumber : mLineNumber;
}
void SetInError(bool aInError)
{
mInError = aInError;
}
bool IsInError()
{
return mInError;
}
void SetAttributeCount(int16_t aValue) { mAttrCount = aValue; }
/**
* perform self test.
* @update gess5/11/98
*/
virtual void SelfTest(void);
static int GetTokenCount();
protected:
int32_t mTypeID;
int32_t mUseCount;
int32_t mNewlineCount;
uint32_t mLineNumber : 31;
uint32_t mInError : 1;
int16_t mAttrCount;
};
#endif

File diff suppressed because it is too large Load Diff

View File

@ -4,90 +4,15 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/**
* MODULE NOTES:
*
* NavDTD is an implementation of the nsIDTD interface.
* In particular, this class captures the behaviors of the original
* Navigator parser productions.
*
* This DTD, like any other in NGLayout, provides a few basic services:
* - First, the DTD collaborates with the Parser class to convert plain
* text into a sequence of HTMLTokens.
* - Second, the DTD describes containment rules for known elements.
* - Third the DTD controls and coordinates the interaction between the
* parsing system and content sink. (The content sink is the interface
* that serves as a proxy for content model).
* - Fourth the DTD maintains an internal style-stack to handle residual (leaky)
* style tags.
*
* You're most likely working in this class file because
* you want to add or change a behavior inherent in this DTD. The remainder
* of this section will describe what you need to do to affect the kind of
* change you want in this DTD.
*
* RESIDUAL-STYLE HANDLNG:
* There are a number of ways to represent style in an HTML document.
* 1) explicit style tags (<B>, <I> etc)
* 2) implicit styles (like those implicit in <Hn>)
* 3) CSS based styles
*
* Residual style handling results from explicit style tags that are
* not closed. Consider this example: <p>text <b>bold </p>
* When the <p> tag closes, the <b> tag is NOT automatically closed.
* Unclosed style tags are handled by the process we call residual-style
* tag handling.
*
* There are two aspects to residual style tag handling. The first is the
* construction and managing of a stack of residual style tags. The
* second is the automatic emission of residual style tags onto leaf content
* in subsequent portions of the document.This step is necessary to propagate
* the expected style behavior to subsequent portions of the document.
*
* Construction and managing the residual style stack is an inline process that
* occurs during the model building phase of the parse process. During the model-
* building phase of the parse process, a content stack is maintained which tracks
* the open container hierarchy. If a style tag(s) fails to be closed when a normal
* container is closed, that style tag is placed onto the residual style stack. If
* that style tag is subsequently closed (in most contexts), it is popped off the
* residual style stack -- and are of no further concern.
*
* Residual style tag emission occurs when the style stack is not empty, and leaf
* content occurs. In our earlier example, the <b> tag "leaked" out of the <p>
* container. Just before the next leaf is emitted (in this or another container) the
* style tags that are on the stack are emitted in succession. These same residual
* style tags get closed automatically when the leaf's container closes, or if a
* child container is opened.
*
*
*/
#ifndef NS_NAVHTMLDTD__
#define NS_NAVHTMLDTD__
#include "nsIDTD.h"
#include "nsISupports.h"
#include "nsHTMLTags.h"
#include "nsDeque.h"
#include "nsParserCIID.h"
#include "nsDTDUtils.h"
#include "nsParser.h"
#include "nsCycleCollectionParticipant.h"
#include "nsCOMPtr.h"
// This class is no longer useful.
class nsIHTMLContentSink;
class nsIParserNode;
class nsDTDContext;
class nsEntryStack;
class nsITokenizer;
class nsCParserNode;
class nsTokenAllocator;
/***************************************************************
Now the main event: CNavDTD.
This not so simple class performs all the duties of token
construction and model building. It works in conjunction with
an nsParser.
***************************************************************/
#ifdef _MSC_VER
#pragma warning( disable : 4275 )
@ -100,274 +25,14 @@ class CNavDTD : public nsIDTD
#endif
public:
/**
* Common constructor for navdtd. You probably want to call
* NS_NewNavHTMLDTD().
*/
CNavDTD();
virtual ~CNavDTD();
/**
* This method is offered publically for the sole use from
* nsParser::ParseFragment. In general, you should prefer to use methods
* that are directly on nsIDTD, since those will be guaranteed to do the
* right thing.
*
* @param aNode The parser node that contains the token information for
* this tag.
* @param aTag The actual tag that is being opened (should correspond to
* aNode.
* @param aStyleStack The style stack that aNode might be a member of
* (usually null).
*/
nsresult OpenContainer(const nsCParserNode *aNode,
eHTMLTags aTag,
nsEntryStack* aStyleStack = nullptr);
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_ISUPPORTS
NS_DECL_NSIDTD
NS_DECL_CYCLE_COLLECTION_CLASS(CNavDTD)
private:
/**
* This method is called to determine whether or not a tag
* of one type can contain a tag of another type.
*
* @param aParent Tag of parent container
* @param aChild Tag of child container
* @return true if parent can contain child
*/
bool CanPropagate(eHTMLTags aParent,
eHTMLTags aChild,
int32_t aParentContains);
/**
* This method gets called to determine whether a given
* child tag can be omitted by the given parent.
*
* @param aParent Parent tag being asked about omitting given child
* @param aChild Child tag being tested for omittability by parent
* @param aParentContains Can be 0,1,-1 (false,true, unknown)
* XXX should be int32_t, not bool
* @return true if given tag can be omitted
*/
bool CanOmit(eHTMLTags aParent,
eHTMLTags aChild,
int32_t& aParentContains);
/**
* Looking at aParent, try to see if we can propagate from aChild to
* aParent. If aParent is a TR tag, then see if we can start at TD instead
* of at aChild.
*
* @param aParent Tag type of parent
* @param aChild Tag type of child
* @return true if closure was achieved -- otherwise false
*/
bool ForwardPropagate(nsString& aSequence,
eHTMLTags aParent,
eHTMLTags aChild);
/**
* Given aParent that does not contain aChild, starting with aChild's
* first root tag, try to find aParent. If we can reach aParent simply by
* going up each first root tag, then return true. Otherwise, we could not
* propagate from aChild up to aParent, so return false.
*
* @param aParent Tag type of parent
* @param aChild Tag type of child
* @return true if closure was achieved -- other false
*/
bool BackwardPropagate(nsString& aSequence,
eHTMLTags aParent,
eHTMLTags aChild) const;
/**
* Attempt forward and/or backward propagation for the given child within
* the current context vector stack. And actually open the required tags.
*
* @param aParent The tag we're trying to open this element inside of.
* @param aChild Type of child to be propagated.
*/
void CreateContextStackFor(eHTMLTags aParent, eHTMLTags aChild);
/**
* Ask if a given container is open anywhere on its stack
*
* @param id of container you want to test for
* @return TRUE if the given container type is open -- otherwise FALSE
*/
bool HasOpenContainer(eHTMLTags aContainer) const;
/**
* This method allows the caller to determine if a any member
* in a set of tags is currently open.
*
* @param aTagSet A set of tags you care about.
* @return true if any of the members of aTagSet are currently open.
*/
bool HasOpenContainer(const eHTMLTags aTagSet[], int32_t aCount) const;
/**
* Accessor that retrieves the tag type of the topmost item on the DTD's
* tag stack.
*
* @return The tag type (may be unknown)
*/
eHTMLTags GetTopNode() const;
/**
* Finds the topmost occurrence of given tag within context vector stack.
*
* @param tag to be found
* @return index of topmost tag occurrence -- may be -1 (kNotFound).
*/
int32_t LastOf(eHTMLTags aTagSet[], int32_t aCount) const;
nsresult HandleToken(CToken* aToken);
/**
* This method gets called when a start token has been
* encountered in the parse process. If the current container
* can contain this tag, then add it. Otherwise, you have
* two choices: 1) create an implicit container for this tag
* to be stored in
* 2) close the top container, and add this to
* whatever container ends up on top.
*
* @param aToken -- next (start) token to be handled
* @return Whether or not we should block the parser.
*/
nsresult HandleStartToken(CToken* aToken);
/**
* This method gets called when a start token has been
* encountered in the parse process. If the current container
* can contain this tag, then add it. Otherwise, you have
* two choices: 1) create an implicit container for this tag
* to be stored in
* 2) close the top container, and add this to
* whatever container ends up on top.
*
* @param aToken Next (start) token to be handled.
* @param aChildTag The tag corresponding to aToken.
* @param aNode CParserNode representing this start token
* @return A potential request to block the parser.
*/
nsresult HandleDefaultStartToken(CToken* aToken, eHTMLTags aChildTag,
nsCParserNode *aNode);
nsresult HandleEndToken(CToken* aToken);
nsresult HandleEntityToken(CToken* aToken);
nsresult HandleCommentToken(CToken* aToken);
nsresult HandleAttributeToken(CToken* aToken);
nsresult HandleProcessingInstructionToken(CToken* aToken);
nsresult HandleDocTypeDeclToken(CToken* aToken);
nsresult BuildNeglectedTarget(eHTMLTags aTarget, eHTMLTokenTypes aType);
nsresult OpenHTML(const nsCParserNode *aNode);
nsresult OpenBody(const nsCParserNode *aNode);
/**
* The special purpose methods automatically close
* one or more open containers.
* @return error code - 0 if all went well.
*/
nsresult CloseContainer(const eHTMLTags aTag, bool aMalformed);
nsresult CloseContainersTo(eHTMLTags aTag, bool aClosedByStartTag);
nsresult CloseContainersTo(int32_t anIndex, eHTMLTags aTag,
bool aClosedByStartTag);
nsresult CloseResidualStyleTags(const eHTMLTags aTag,
bool aClosedByStartTag);
/**
* Causes leaf to be added to sink at current vector pos.
* @param aNode is leaf node to be added.
* @return error code - 0 if all went well.
*/
nsresult AddLeaf(const nsIParserNode *aNode);
nsresult AddHeadContent(nsIParserNode *aNode);
/**
* This set of methods is used to create and manage the set of
* transient styles that occur as a result of poorly formed HTML
* or bugs in the original navigator.
*
* @param aTag -- represents the transient style tag to be handled.
* @return error code -- usually 0
*/
nsresult OpenTransientStyles(eHTMLTags aChildTag,
bool aCloseInvalid = true);
void PopStyle(eHTMLTags aTag);
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,int32_t aCount);
/**
* This gets called before we've handled a given start tag.
* It's a generic hook to let us do pre processing.
*
* @param aToken contains the tag in question
* @param aTag is the tag itself.
* @param aNode is the node (tag) with associated attributes.
* @return NS_OK if we should continue, a failure code otherwise.
*/
nsresult WillHandleStartTag(CToken* aToken,eHTMLTags aChildTag,nsIParserNode& aNode);
nsresult DidHandleStartTag(nsIParserNode& aNode,eHTMLTags aChildTag);
/**
* This method gets called when a start token has been encountered that
* the parent wants to omit. It stashes it in the current element if that
* element accepts such misplaced tokens.
*
* @param aToken Next (start) token to be handled
* @param aChildTag id of the child in question
* @param aParent id of the parent in question
* @param aNode CParserNode representing this start token
*/
void HandleOmittedTag(CToken* aToken, eHTMLTags aChildTag,
eHTMLTags aParent, nsIParserNode *aNode);
nsresult HandleSavedTokens(int32_t anIndex);
nsresult HandleKeyGen(nsIParserNode *aNode);
bool IsAlternateTag(eHTMLTags aTag);
bool IsBlockElement(int32_t aTagID, int32_t aParentID) const;
bool IsInlineElement(int32_t aTagID, int32_t aParentID) const;
nsDeque mMisplacedContent;
nsCOMPtr<nsIHTMLContentSink> mSink;
nsTokenAllocator* mTokenAllocator;
nsDTDContext* mBodyContext;
nsDTDContext* mTempContext;
bool mCountLines;
nsITokenizer* mTokenizer; // weak
nsString mFilename;
nsString mScratch; //used for various purposes; non-persistent
nsCString mMimeType;
nsNodeAllocator mNodeAllocator;
nsDTDMode mDTDMode;
eParserDocType mDocType;
eParserCommands mParserCommand; //tells us to viewcontent/viewsource/viewerrors...
int32_t mLineNumber;
int32_t mOpenMapCount;
int32_t mHeadContainerPosition;
uint16_t mFlags;
};
#endif
#endif

View File

@ -12,6 +12,7 @@
#include "nsIHTMLContentSink.h"
#include "nsHTMLTokenizer.h"
#include "nsMimeTypes.h"
#include "nsHTMLTokenizer.h"
CParserContext::CParserContext(CParserContext* aPrevContext,
nsScanner* aScanner,
@ -78,12 +79,6 @@ CParserContext::GetTokenizer(nsIDTD* aDTD,
if (!mTokenizer) {
return NS_ERROR_OUT_OF_MEMORY;
}
// Make sure the new tokenizer has all of the necessary information.
// XXX this might not be necessary.
if (mPrevContext) {
mTokenizer->CopyState(mPrevContext->mTokenizer);
}
}
else if (type == NS_IPARSER_FLAG_XML) {
mTokenizer = do_QueryInterface(aDTD, &result);

View File

@ -9,13 +9,11 @@ MODULE = 'htmlparser'
CPP_SOURCES += [
'CNavDTD.cpp',
'CParserContext.cpp',
'nsDTDUtils.cpp',
'nsElementTable.cpp',
'nsExpatDriver.cpp',
'nsHTMLEntities.cpp',
'nsHTMLTags.cpp',
'nsHTMLTokenizer.cpp',
'nsHTMLTokens.cpp',
'nsParser.cpp',
'nsParserModule.cpp',
'nsParserMsgUtils.cpp',
@ -23,7 +21,6 @@ CPP_SOURCES += [
'nsParserService.cpp',
'nsScanner.cpp',
'nsScannerString.cpp',
'nsToken.cpp',
]
LIBRARY_NAME = 'htmlpars'

View File

@ -1,985 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=2 sw=2 et tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "nsIAtom.h"
#include "nsDTDUtils.h"
#include "CNavDTD.h"
#include "nsIParserNode.h"
#include "nsParserNode.h"
#include "nsIChannel.h"
#include "nsIServiceManager.h"
#include "nsUnicharUtils.h"
/**************************************************************************************
A few notes about how residual style handling is performed:
1. The style stack contains nsTagEntry elements.
2. Every tag on the containment stack can have it's own residual style stack.
3. When a style leaks, it's mParent member is set to the level on the stack where
it originated. A node with an mParent of 0 is not opened on tag stack,
but is open on stylestack.
4. An easy way to tell that a container on the element stack is a residual style tag
is that it's use count is >1.
**************************************************************************************/
/**
* Default constructor
* @update harishd 04/04/99
* @update gess 04/22/99
*/
nsEntryStack::nsEntryStack() {
MOZ_COUNT_CTOR(nsEntryStack);
mCapacity=0;
mCount=0;
mEntries=0;
}
/**
* Default destructor
* @update harishd 04/04/99
* @update gess 04/22/99
*/
nsEntryStack::~nsEntryStack() {
MOZ_COUNT_DTOR(nsEntryStack);
if(mEntries) {
//add code here to recycle the node if you have one...
delete [] mEntries;
mEntries=0;
}
mCount=mCapacity=0;
}
/**
* Release all objects in the entry stack
*/
void
nsEntryStack::ReleaseAll(nsNodeAllocator* aNodeAllocator)
{
NS_ASSERTION(aNodeAllocator,"no allocator? - potential leak!");
if(aNodeAllocator) {
NS_ASSERTION(mCount >= 0,"count should not be negative");
while(mCount > 0) {
nsCParserNode* node=this->Pop();
IF_FREE(node,aNodeAllocator);
}
}
}
/**
* Resets state of stack to be empty.
* @update harishd 04/04/99
*/
void nsEntryStack::Empty(void) {
mCount=0;
}
/**
*
* @update gess 04/22/99
*/
void nsEntryStack::EnsureCapacityFor(int32_t aNewMax,int32_t aShiftOffset) {
if(mCapacity<aNewMax){
const int kDelta=16;
int32_t theSize = kDelta * ((aNewMax / kDelta) + 1);
nsTagEntry* temp=new nsTagEntry[theSize];
mCapacity=theSize;
if(temp){
int32_t index=0;
for(index=0;index<mCount;++index) {
temp[aShiftOffset+index]=mEntries[index];
}
if(mEntries) delete [] mEntries;
mEntries=temp;
}
else{
//XXX HACK! This is very bad! We failed to get memory.
}
} //if
}
/**
*
* @update gess 04/22/99
*/
void nsEntryStack::Push(nsCParserNode* aNode,
nsEntryStack* aStyleStack,
bool aRefCntNode)
{
if(aNode) {
EnsureCapacityFor(mCount+1);
mEntries[mCount].mTag = (eHTMLTags)aNode->GetNodeType();
if (aRefCntNode) {
aNode->mUseCount++;
mEntries[mCount].mNode = const_cast<nsCParserNode*>(aNode);
IF_HOLD(mEntries[mCount].mNode);
}
mEntries[mCount].mParent=aStyleStack;
mEntries[mCount++].mStyles=0;
}
}
void nsEntryStack::PushTag(eHTMLTags aTag)
{
EnsureCapacityFor(mCount + 1);
mEntries[mCount].mTag = aTag;
mEntries[mCount].mParent = nullptr;
mEntries[mCount].mStyles = nullptr;
++mCount;
}
/**
* This method inserts the given node onto the front of this stack
*
* @update gess 11/10/99
*/
void nsEntryStack::PushFront(nsCParserNode* aNode,
nsEntryStack* aStyleStack,
bool aRefCntNode)
{
if(aNode) {
if(mCount<mCapacity) {
int32_t index=0;
for(index=mCount;index>0;index--) {
mEntries[index]=mEntries[index-1];
}
}
else {
EnsureCapacityFor(mCount+1,1);
}
mEntries[0].mTag = (eHTMLTags)aNode->GetNodeType();
if (aRefCntNode) {
aNode->mUseCount++;
mEntries[0].mNode = const_cast<nsCParserNode*>(aNode);
IF_HOLD(mEntries[0].mNode);
}
mEntries[0].mParent=aStyleStack;
mEntries[0].mStyles=0;
++mCount;
}
}
/**
*
* @update gess 11/10/99
*/
void nsEntryStack::Append(nsEntryStack *aStack) {
if(aStack) {
int32_t theCount=aStack->mCount;
EnsureCapacityFor(mCount+aStack->mCount,0);
int32_t theIndex=0;
for(theIndex=0;theIndex<theCount;++theIndex){
mEntries[mCount]=aStack->mEntries[theIndex];
mEntries[mCount++].mParent=0;
}
}
}
/**
* This method removes the node for the given tag
* from anywhere within this entry stack, and shifts
* other entries down.
*
* NOTE: It's odd to be removing an element from the middle
* of a stack, but it's necessary because of how MALFORMED
* html can be.
*
* anIndex: the index within the stack of the tag to be removed
* aTag: the id of the tag to be removed
* @update gess 02/25/00
*/
nsCParserNode* nsEntryStack::Remove(int32_t anIndex,
eHTMLTags aTag)
{
nsCParserNode* result = 0;
if (0 < mCount && anIndex < mCount){
result = mEntries[anIndex].mNode;
if (result)
result->mUseCount--;
int32_t theIndex = 0;
mCount -= 1;
for( theIndex = anIndex; theIndex < mCount; ++theIndex){
mEntries[theIndex] = mEntries[theIndex+1];
}
mEntries[mCount].mNode = 0;
mEntries[mCount].mStyles = 0;
nsEntryStack* theStyleStack = mEntries[anIndex].mParent;
if (theStyleStack) {
//now we have to tell the residual style stack where this tag
//originated that it's no longer in use.
uint32_t scount = theStyleStack->mCount;
#ifdef DEBUG_mrbkap
NS_ASSERTION(scount != 0, "RemoveStyles has a bad style stack");
#endif
nsTagEntry *theStyleEntry = theStyleStack->mEntries;
for (uint32_t sindex = scount-1;; --sindex) {
if (theStyleEntry->mTag == aTag) {
// This tells us that the style is not open at any level.
theStyleEntry->mParent = nullptr;
break;
}
if (sindex == 0) {
#ifdef DEBUG_mrbkap
NS_ERROR("Couldn't find the removed style on its parent stack");
#endif
break;
}
++theStyleEntry;
}
}
}
return result;
}
/**
* Pops an entry from this style stack. If the entry has a parent stack, it
* updates the entry so that we know not to try to remove it from the parent
* stack since it's no longer open.
*/
nsCParserNode* nsEntryStack::Pop(void)
{
nsCParserNode* result = 0;
if (0 < mCount) {
result = mEntries[--mCount].mNode;
if (result)
result->mUseCount--;
mEntries[mCount].mNode = 0;
mEntries[mCount].mStyles = 0;
nsEntryStack* theStyleStack = mEntries[mCount].mParent;
if (theStyleStack) {
//now we have to tell the residual style stack where this tag
//originated that it's no longer in use.
uint32_t scount = theStyleStack->mCount;
// XXX If this NS_ENSURE_TRUE fails, it means that the style stack was
// empty before we were removed.
#ifdef DEBUG_mrbkap
NS_ASSERTION(scount != 0, "preventing a potential crash.");
#endif
NS_ENSURE_TRUE(scount != 0, result);
nsTagEntry *theStyleEntry = theStyleStack->mEntries;
for (uint32_t sindex = scount - 1;; --sindex) {
if (theStyleEntry->mTag == mEntries[mCount].mTag) {
// This tells us that the style is not open at any level
theStyleEntry->mParent = nullptr;
break;
}
if (sindex == 0) {
#ifdef DEBUG_mrbkap
NS_ERROR("Couldn't find the removed style on its parent stack");
#endif
break;
}
++theStyleEntry;
}
}
}
return result;
}
/**
*
* @update harishd 04/04/99
* @update gess 04/21/99
*/
eHTMLTags nsEntryStack::First() const
{
eHTMLTags result=eHTMLTag_unknown;
if(0<mCount){
result=mEntries[0].mTag;
}
return result;
}
/**
*
* @update harishd 04/04/99
* @update gess 04/21/99
*/
nsCParserNode* nsEntryStack::NodeAt(int32_t anIndex) const
{
nsCParserNode* result=0;
if((0<mCount) && (anIndex<mCount)) {
result=mEntries[anIndex].mNode;
}
return result;
}
/**
*
* @update harishd 04/04/99
* @update gess 04/21/99
*/
eHTMLTags nsEntryStack::TagAt(int32_t anIndex) const
{
eHTMLTags result=eHTMLTag_unknown;
if((0<mCount) && (anIndex<mCount)) {
result=mEntries[anIndex].mTag;
}
return result;
}
/**
*
* @update gess 04/21/99
*/
nsTagEntry* nsEntryStack::EntryAt(int32_t anIndex) const
{
nsTagEntry *result=0;
if((0<mCount) && (anIndex<mCount)) {
result=&mEntries[anIndex];
}
return result;
}
/**
*
* @update harishd 04/04/99
* @update gess 04/21/99
*/
eHTMLTags nsEntryStack::operator[](int32_t anIndex) const
{
eHTMLTags result=eHTMLTag_unknown;
if((0<mCount) && (anIndex<mCount)) {
result=mEntries[anIndex].mTag;
}
return result;
}
/**
*
* @update harishd 04/04/99
* @update gess 04/21/99
*/
eHTMLTags nsEntryStack::Last(void) const
{
eHTMLTags result=eHTMLTag_unknown;
if(0<mCount) {
result=mEntries[mCount-1].mTag;
}
return result;
}
nsTagEntry*
nsEntryStack::PopEntry()
{
nsTagEntry* entry = EntryAt(mCount-1);
this->Pop();
return entry;
}
void nsEntryStack::PushEntry(nsTagEntry* aEntry,
bool aRefCntNode)
{
if (aEntry) {
EnsureCapacityFor(mCount+1);
mEntries[mCount].mNode = aEntry->mNode;
mEntries[mCount].mTag = aEntry->mTag;
mEntries[mCount].mParent = aEntry->mParent;
mEntries[mCount].mStyles = aEntry->mStyles;
if (aRefCntNode && mEntries[mCount].mNode) {
mEntries[mCount].mNode->mUseCount++;
IF_HOLD(mEntries[mCount].mNode);
}
mCount++;
}
}
/***************************************************************
Now define the dtdcontext class
***************************************************************/
/**
*
* @update gess 04.21.2000
*/
nsDTDContext::nsDTDContext() : mStack()
{
MOZ_COUNT_CTOR(nsDTDContext);
mResidualStyleCount=0;
mContextTopIndex=-1;
mTokenAllocator=0;
mNodeAllocator=0;
#ifdef DEBUG
memset(mXTags,0,sizeof(mXTags));
#endif
}
/**
*
* @update gess9/10/98
*/
nsDTDContext::~nsDTDContext()
{
MOZ_COUNT_DTOR(nsDTDContext);
}
/**
*
* @update gess7/9/98
*/
bool nsDTDContext::HasOpenContainer(eHTMLTags aTag) const {
int32_t theIndex=mStack.LastOf(aTag);
return bool(-1<theIndex);
}
/**
*
* @update gess7/9/98
*/
void nsDTDContext::Push(nsCParserNode* aNode,
nsEntryStack* aStyleStack,
bool aRefCntNode) {
if(aNode) {
#ifdef DEBUG
eHTMLTags theTag = (eHTMLTags)aNode->GetNodeType();
int size = mStack.mCount;
if (size < eMaxTags)
mXTags[size] = theTag;
#endif
mStack.Push(aNode, aStyleStack, aRefCntNode);
}
}
void nsDTDContext::PushTag(eHTMLTags aTag)
{
#ifdef DEBUG
if (mStack.mCount < eMaxTags) {
mXTags[mStack.mCount] = aTag;
}
#endif
mStack.PushTag(aTag);
}
nsTagEntry*
nsDTDContext::PopEntry()
{
int32_t theSize = mStack.mCount;
if(0<theSize) {
#ifdef DEBUG
if (theSize <= eMaxTags)
mXTags[theSize-1]=eHTMLTag_unknown;
#endif
return mStack.PopEntry();
}
return 0;
}
void nsDTDContext::PushEntry(nsTagEntry* aEntry,
bool aRefCntNode)
{
#ifdef DEBUG
int size=mStack.mCount;
if(size< eMaxTags && aEntry)
mXTags[size]=aEntry->mTag;
#endif
mStack.PushEntry(aEntry, aRefCntNode);
}
/* This method will move the top entries, in the entry-stack, into dest context.
* @param aDest - Destination context for the entries.
* @param aCount - Number of entries, on top of the entry-stack, to be moved.
*/
void
nsDTDContext::MoveEntries(nsDTDContext& aDest,
int32_t aCount)
{
NS_ASSERTION(aCount > 0 && mStack.mCount >= aCount, "cannot move entries");
if (aCount > 0 && mStack.mCount >= aCount) {
while (aCount) {
aDest.PushEntry(&mStack.mEntries[--mStack.mCount], false);
#ifdef DEBUG
if (mStack.mCount < eMaxTags) {
mXTags[mStack.mCount] = eHTMLTag_unknown;
}
#endif
--aCount;
}
}
}
/**
* @update gess 11/11/99,
* harishd 04/04/99
*/
nsCParserNode* nsDTDContext::Pop(nsEntryStack *&aChildStyleStack) {
int32_t theSize=mStack.mCount;
nsCParserNode* result=0;
if(0<theSize) {
#ifdef DEBUG
if ((theSize>0) && (theSize <= eMaxTags))
mXTags[theSize-1]=eHTMLTag_unknown;
#endif
nsTagEntry* theEntry=mStack.EntryAt(mStack.mCount-1);
aChildStyleStack=theEntry->mStyles;
result=mStack.Pop();
theEntry->mParent=0;
}
return result;
}
/**
*
* @update harishd 04/07/00
*/
nsCParserNode* nsDTDContext::Pop() {
nsEntryStack *theTempStyleStack=0; // This has no use here...
return Pop(theTempStyleStack);
}
/**
*
* @update gess7/9/98
*/
eHTMLTags nsDTDContext::First(void) const {
return mStack.First();
}
/**
*
* @update gess7/9/98
*/
eHTMLTags nsDTDContext::TagAt(int32_t anIndex) const {
return mStack.TagAt(anIndex);
}
/**
*
* @update gess7/9/98
*/
nsTagEntry* nsDTDContext::LastEntry(void) const {
return mStack.EntryAt(mStack.mCount-1);
}
/**
*
* @update gess7/9/98
*/
eHTMLTags nsDTDContext::Last() const {
return mStack.Last();
}
/**
*
* @update gess7/9/98
*/
nsEntryStack* nsDTDContext::GetStylesAt(int32_t anIndex) const {
nsEntryStack* result=0;
if(anIndex<mStack.mCount){
nsTagEntry* theEntry=mStack.EntryAt(anIndex);
if(theEntry) {
result=theEntry->mStyles;
}
}
return result;
}
/**
*
* @update gess 04/28/99
*/
void nsDTDContext::PushStyle(nsCParserNode* aNode){
nsTagEntry* theEntry=mStack.EntryAt(mStack.mCount-1);
if(theEntry ) {
nsEntryStack* theStack=theEntry->mStyles;
if(!theStack) {
theStack=theEntry->mStyles=new nsEntryStack();
}
if(theStack) {
theStack->Push(aNode);
++mResidualStyleCount;
}
} //if
}
/**
* Call this when you have an EntryStack full of styles
* that you want to push at this level.
*
* @update gess 04/28/99
*/
void nsDTDContext::PushStyles(nsEntryStack *aStyles){
if(aStyles) {
nsTagEntry* theEntry=mStack.EntryAt(mStack.mCount-1);
if(theEntry ) {
nsEntryStack* theStyles=theEntry->mStyles;
if(!theStyles) {
theEntry->mStyles=aStyles;
uint32_t scount=aStyles->mCount;
uint32_t sindex=0;
theEntry=aStyles->mEntries;
for(sindex=0;sindex<scount;++sindex){
theEntry->mParent=0; //this tells us that the style is not open at any level
++theEntry;
++mResidualStyleCount;
} //for
}
else {
theStyles->Append(aStyles);
// Delete aStyles since it has been copied to theStyles...
delete aStyles;
aStyles=0;
}
} //if(theEntry )
else if(mStack.mCount==0) {
// If you're here it means that we have hit the rock bottom
// ,of the stack, and there's no need to handle anymore styles.
// Fix for bug 29048
IF_DELETE(aStyles,mNodeAllocator);
}
}//if(aStyles)
}
/**
*
* @update gess 04/28/99
*/
nsCParserNode* nsDTDContext::PopStyle(void){
nsCParserNode *result=0;
nsTagEntry *theEntry=mStack.EntryAt(mStack.mCount-1);
if(theEntry && (theEntry->mNode)) {
nsEntryStack* theStyleStack=theEntry->mParent;
if(theStyleStack){
result=theStyleStack->Pop();
mResidualStyleCount--;
}
} //if
return result;
}
/**
*
* @update gess 04/28/99
*/
nsCParserNode* nsDTDContext::PopStyle(eHTMLTags aTag){
int32_t theLevel=0;
nsCParserNode* result=0;
for(theLevel=mStack.mCount-1;theLevel>0;theLevel--) {
nsEntryStack *theStack=mStack.mEntries[theLevel].mStyles;
if(theStack) {
if(aTag==theStack->Last()) {
result=theStack->Pop();
mResidualStyleCount--;
break; // Fix bug 50710 - Stop after finding a style.
} else {
// NS_ERROR("bad residual style entry");
}
}
}
return result;
}
/**
*
* This is similar to popstyle, except that it removes the
* style tag given from anywhere in the style stack, and
* not just at the top.
*
* @update gess 01/26/00
*/
void nsDTDContext::RemoveStyle(eHTMLTags aTag){
int32_t theLevel=mStack.mCount;
while (theLevel) {
nsEntryStack *theStack=GetStylesAt(--theLevel);
if (theStack) {
int32_t index=theStack->mCount;
while (index){
nsTagEntry *theEntry=theStack->EntryAt(--index);
if (aTag==(eHTMLTags)theEntry->mNode->GetNodeType()) {
mResidualStyleCount--;
nsCParserNode* result=theStack->Remove(index,aTag);
IF_FREE(result, mNodeAllocator);
return;
}
}
}
}
}
/**
* This gets called when the parser module is getting unloaded
*
* @return nada
*/
void nsDTDContext::ReleaseGlobalObjects(void){
}
/**************************************************************
Now define the nsTokenAllocator class...
**************************************************************/
/**
*
* @update gess7/25/98
* @param
*/
nsTokenAllocator::nsTokenAllocator() {
MOZ_COUNT_CTOR(nsTokenAllocator);
#ifdef DEBUG
int i=0;
for(i=0;i<eToken_last-1;++i) {
mTotals[i]=0;
}
#endif
}
/**
* Destructor for the token factory
* @update gess7/25/98
*/
nsTokenAllocator::~nsTokenAllocator() {
MOZ_COUNT_DTOR(nsTokenAllocator);
}
class CTokenFinder: public nsDequeFunctor{
public:
CTokenFinder(CToken* aToken) {mToken=aToken;}
virtual void* operator()(void* anObject) {
if(anObject==mToken) {
return anObject;
}
return 0;
}
CToken* mToken;
};
/**
* Let's get this code ready to be reused by all the contexts.
*
* @update rickg 12June2000
* @param aType -- tells you the type of token to create
* @param aTag -- tells you the type of tag to init with this token
* @param aString -- gives a default string value for the token
*
* @return ptr to new token (or 0).
*/
CToken* nsTokenAllocator::CreateTokenOfType(eHTMLTokenTypes aType,eHTMLTags aTag, const nsAString& aString) {
CToken* result=0;
#ifdef DEBUG
mTotals[aType-1]++;
#endif
switch(aType){
case eToken_start: result=new(mArenaPool) CStartToken(aString, aTag); break;
case eToken_end: result=new(mArenaPool) CEndToken(aString, aTag); break;
case eToken_comment: result=new(mArenaPool) CCommentToken(aString); break;
case eToken_entity: result=new(mArenaPool) CEntityToken(aString); break;
case eToken_whitespace: result=new(mArenaPool) CWhitespaceToken(aString); break;
case eToken_newline: result=new(mArenaPool) CNewlineToken(); break;
case eToken_text: result=new(mArenaPool) CTextToken(aString); break;
case eToken_attribute: result=new(mArenaPool) CAttributeToken(aString); break;
case eToken_instruction: result=new(mArenaPool) CInstructionToken(aString); break;
case eToken_cdatasection: result=new(mArenaPool) CCDATASectionToken(aString); break;
case eToken_doctypeDecl: result=new(mArenaPool) CDoctypeDeclToken(aString); break;
case eToken_markupDecl: result=new(mArenaPool) CMarkupDeclToken(aString); break;
default:
NS_ASSERTION(false, "nsDTDUtils::CreateTokenOfType: illegal token type");
break;
}
return result;
}
/**
* Let's get this code ready to be reused by all the contexts.
*
* @update rickg 12June2000
* @param aType -- tells you the type of token to create
* @param aTag -- tells you the type of tag to init with this token
*
* @return ptr to new token (or 0).
*/
CToken* nsTokenAllocator::CreateTokenOfType(eHTMLTokenTypes aType,eHTMLTags aTag) {
CToken* result=0;
#ifdef DEBUG
mTotals[aType-1]++;
#endif
switch(aType){
case eToken_start: result=new(mArenaPool) CStartToken(aTag); break;
case eToken_end: result=new(mArenaPool) CEndToken(aTag); break;
case eToken_comment: result=new(mArenaPool) CCommentToken(); break;
case eToken_attribute: result=new(mArenaPool) CAttributeToken(); break;
case eToken_entity: result=new(mArenaPool) CEntityToken(); break;
case eToken_whitespace: result=new(mArenaPool) CWhitespaceToken(); break;
case eToken_newline: result=new(mArenaPool) CNewlineToken(); break;
case eToken_text: result=new(mArenaPool) CTextToken(); break;
case eToken_instruction: result=new(mArenaPool) CInstructionToken(); break;
case eToken_cdatasection: result=new(mArenaPool) CCDATASectionToken(aTag); break;
case eToken_doctypeDecl: result=new(mArenaPool) CDoctypeDeclToken(aTag); break;
case eToken_markupDecl: result=new(mArenaPool) CMarkupDeclToken(); break;
default:
NS_ASSERTION(false, "nsDTDUtils::CreateTokenOfType: illegal token type");
break;
}
return result;
}
#ifdef DEBUG_TRACK_NODES
static nsCParserNode* gAllNodes[100];
static int gAllNodeCount=0;
int FindNode(nsCParserNode *aNode) {
int theIndex=0;
for(theIndex=0;theIndex<gAllNodeCount;++theIndex) {
if(gAllNodes[theIndex]==aNode) {
return theIndex;
}
}
return -1;
}
void AddNode(nsCParserNode *aNode) {
if(-1==FindNode(aNode)) {
gAllNodes[gAllNodeCount++]=aNode;
}
else {
//you tried to recycle a node twice!
}
}
void RemoveNode(nsCParserNode *aNode) {
int theIndex=FindNode(aNode);
if(-1<theIndex) {
gAllNodes[theIndex]=gAllNodes[--gAllNodeCount];
}
}
#endif
#ifdef HEAP_ALLOCATED_NODES
nsNodeAllocator::nsNodeAllocator():mSharedNodes(0){
#ifdef DEBUG_TRACK_NODES
mCount=0;
#endif
#else
nsNodeAllocator::nsNodeAllocator() {
#endif
MOZ_COUNT_CTOR(nsNodeAllocator);
}
nsNodeAllocator::~nsNodeAllocator() {
MOZ_COUNT_DTOR(nsNodeAllocator);
#ifdef HEAP_ALLOCATED_NODES
nsCParserNode* theNode = 0;
while((theNode=(nsCParserNode*)mSharedNodes.Pop())){
#ifdef DEBUG_TRACK_NODES
RemoveNode(theNode);
#endif
::operator delete(theNode);
theNode=nullptr;
}
#ifdef DEBUG_TRACK_NODES
if(mCount) {
printf("**************************\n");
printf("%i out of %i nodes leaked!\n",gAllNodeCount,mCount);
printf("**************************\n");
}
#endif
#endif
}
nsCParserNode* nsNodeAllocator::CreateNode(CToken* aToken,
nsTokenAllocator* aTokenAllocator)
{
nsCParserNode* result = 0;
#ifdef HEAP_ALLOCATED_NODES
#if 0
if(gAllNodeCount!=mSharedNodes.GetSize()) {
int x=10; //this is very BAD!
}
#endif
result = static_cast<nsCParserNode*>(mSharedNodes.Pop());
if (result) {
result->Init(aToken, aTokenAllocator,this);
}
else{
result = nsCParserNode::Create(aToken, aTokenAllocator,this);
#ifdef DEBUG_TRACK_NODES
++mCount;
AddNode(static_cast<nsCParserNode*>(result));
#endif
IF_HOLD(result);
}
#else
eHTMLTokenTypes type = aToken ? eHTMLTokenTypes(aToken->GetTokenType()) : eToken_unknown;
switch (type) {
case eToken_start:
result = nsCParserStartNode::Create(aToken, aTokenAllocator,this);
break;
default :
result = nsCParserNode::Create(aToken, aTokenAllocator,this);
break;
}
IF_HOLD(result);
#endif
return result;
}
#ifdef DEBUG
void DebugDumpContainmentRules(nsIDTD& theDTD,const char* aFilename,const char* aTitle) {
}
#endif

View File

@ -1,453 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=2 sw=2 et tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/**
* MODULE NOTES:
* @update gess 4/1/98
*
*/
#ifndef DTDUTILS_
#define DTDUTILS_
#include "nsHTMLTags.h"
#include "nsHTMLTokens.h"
#include "nsIParser.h"
#include "nsCRT.h"
#include "nsDeque.h"
#include "nsIDTD.h"
#include "nsITokenizer.h"
#include "nsString.h"
#include "nsIParserNode.h"
#include "nsCOMArray.h"
#include "nsIParserService.h"
#include "nsReadableUtils.h"
#include "nsIHTMLContentSink.h"
#include "nsIFrame.h"
#define IF_HOLD(_ptr) \
PR_BEGIN_MACRO \
if(_ptr) { \
_ptr->AddRef(); \
} \
PR_END_MACRO
// recycles _ptr
#define IF_FREE(_ptr, _allocator) \
PR_BEGIN_MACRO \
if(_ptr && _allocator) { \
_ptr->Release((_allocator)->GetArenaPool()); \
_ptr=0; \
} \
PR_END_MACRO
// release objects and destroy _ptr
#define IF_DELETE(_ptr, _allocator) \
PR_BEGIN_MACRO \
if(_ptr) { \
_ptr->ReleaseAll(_allocator); \
delete(_ptr); \
_ptr=0; \
} \
PR_END_MACRO
class nsIParserNode;
class nsCParserNode;
class nsNodeAllocator;
#ifdef DEBUG
void DebugDumpContainmentRules(nsIDTD& theDTD,const char* aFilename,const char* aTitle);
void DebugDumpContainmentRules2(nsIDTD& theDTD,const char* aFilename,const char* aTitle);
#endif
/***************************************************************
First, define the tagstack class
***************************************************************/
class nsEntryStack; //forware declare to make compilers happy.
struct nsTagEntry {
nsTagEntry ()
: mTag(eHTMLTag_unknown), mNode(0), mParent(0), mStyles(0){}
eHTMLTags mTag; //for speedier access to tag id
nsCParserNode* mNode;
nsEntryStack* mParent;
nsEntryStack* mStyles;
};
class nsEntryStack {
public:
nsEntryStack();
~nsEntryStack();
nsTagEntry* PopEntry();
void PushEntry(nsTagEntry* aEntry, bool aRefCntNode = true);
void EnsureCapacityFor(int32_t aNewMax, int32_t aShiftOffset=0);
void Push(nsCParserNode* aNode,nsEntryStack* aStyleStack=0, bool aRefCntNode = true);
void PushTag(eHTMLTags aTag);
void PushFront(nsCParserNode* aNode,nsEntryStack* aStyleStack=0, bool aRefCntNode = true);
void Append(nsEntryStack *aStack);
nsCParserNode* Pop(void);
nsCParserNode* Remove(int32_t anIndex,eHTMLTags aTag);
nsCParserNode* NodeAt(int32_t anIndex) const;
eHTMLTags First() const;
eHTMLTags TagAt(int32_t anIndex) const;
nsTagEntry* EntryAt(int32_t anIndex) const;
eHTMLTags operator[](int32_t anIndex) const;
eHTMLTags Last() const;
void Empty(void);
/*
* Release all objects in the entry stack
*/
void ReleaseAll(nsNodeAllocator* aNodeAllocator);
/**
* Find the first instance of given tag on the stack.
* @update gess 12/14/99
* @param aTag
* @return index of tag, or kNotFound if not found
*/
inline int32_t FirstOf(eHTMLTags aTag) const {
int32_t index=-1;
if(0<mCount) {
while(++index<mCount) {
if(aTag==mEntries[index].mTag) {
return index;
}
} //while
}
return kNotFound;
}
/**
* Find the last instance of given tag on the stack.
* @update gess 12/14/99
* @param aTag
* @return index of tag, or kNotFound if not found
*/
inline int32_t LastOf(eHTMLTags aTag) const {
int32_t index=mCount;
while(--index>=0) {
if(aTag==mEntries[index].mTag) {
return index;
}
}
return kNotFound;
}
nsTagEntry* mEntries;
int32_t mCount;
int32_t mCapacity;
};
/**********************************************************
The table state class is used to store info about each
table that is opened on the stack. As tables open and
close on the context, we update these objects to track
what has/hasn't been seen on a per table basis.
**********************************************************/
class CTableState {
public:
CTableState(CTableState *aPreviousState=0) {
mHasCaption=false;
mHasCols=false;
mHasTHead=false;
mHasTFoot=false;
mHasTBody=false;
mPrevious=aPreviousState;
}
bool CanOpenCaption() {
bool result=!(mHasCaption || mHasCols || mHasTHead || mHasTFoot || mHasTBody);
return result;
}
bool CanOpenCols() {
bool result=!(mHasCols || mHasTHead || mHasTFoot || mHasTBody);
return result;
}
bool CanOpenTBody() {
bool result=!(mHasTBody);
return result;
}
bool CanOpenTHead() {
bool result=!(mHasTHead || mHasTFoot || mHasTBody);
return result;
}
bool CanOpenTFoot() {
bool result=!(mHasTFoot || mHasTBody);
return result;
}
bool mHasCaption;
bool mHasCols;
bool mHasTHead;
bool mHasTFoot;
bool mHasTBody;
CTableState *mPrevious;
};
/************************************************************************
nsTokenAllocator class implementation.
This class is used to recycle tokens.
By using this simple class, we cut WAY down on the number of tokens
that get created during the run of the system.
Note: The allocator is created per document. It's been shared
( but not ref. counted ) by objects, tokenizer,dtd,and dtd context,
that cease to exist when the document is destroyed.
************************************************************************/
class nsTokenAllocator
{
public:
nsTokenAllocator();
~nsTokenAllocator();
CToken* CreateTokenOfType(eHTMLTokenTypes aType,eHTMLTags aTag, const nsAString& aString);
CToken* CreateTokenOfType(eHTMLTokenTypes aType,eHTMLTags aTag);
nsDummyAllocator& GetArenaPool() { return mArenaPool; }
protected:
nsDummyAllocator mArenaPool;
#ifdef DEBUG
int mTotals[eToken_last-1];
#endif
};
/************************************************************************
CNodeRecycler class implementation.
This class is used to recycle nodes.
By using this simple class, we cut down on the number of nodes
that get created during the run of the system.
************************************************************************/
#ifndef HEAP_ALLOCATED_NODES
class nsCParserNode;
#endif
class nsNodeAllocator
{
public:
nsNodeAllocator();
~nsNodeAllocator();
nsCParserNode* CreateNode(CToken* aToken=nullptr, nsTokenAllocator* aTokenAllocator=0);
nsDummyAllocator& GetArenaPool() { return mNodePool; }
#ifdef HEAP_ALLOCATED_NODES
void Recycle(nsCParserNode* aNode) { mSharedNodes.Push(static_cast<void*>(aNode)); }
protected:
nsDeque mSharedNodes;
#ifdef DEBUG_TRACK_NODES
int32_t mCount;
#endif
#endif
protected:
nsDummyAllocator mNodePool;
};
/************************************************************************
The dtdcontext class defines an ordered list of tags (a context).
************************************************************************/
class nsDTDContext
{
public:
nsDTDContext();
~nsDTDContext();
nsTagEntry* PopEntry();
void PushEntry(nsTagEntry* aEntry, bool aRefCntNode = true);
void MoveEntries(nsDTDContext& aDest, int32_t aCount);
void Push(nsCParserNode* aNode,nsEntryStack* aStyleStack=0, bool aRefCntNode = true);
void PushTag(eHTMLTags aTag);
nsCParserNode* Pop(nsEntryStack*& aChildStack);
nsCParserNode* Pop();
nsCParserNode* PeekNode() { return mStack.NodeAt(mStack.mCount-1); }
eHTMLTags First(void) const;
eHTMLTags Last(void) const;
nsTagEntry* LastEntry(void) const;
eHTMLTags TagAt(int32_t anIndex) const;
eHTMLTags operator[](int32_t anIndex) const {return TagAt(anIndex);}
bool HasOpenContainer(eHTMLTags aTag) const;
int32_t FirstOf(eHTMLTags aTag) const {return mStack.FirstOf(aTag);}
int32_t LastOf(eHTMLTags aTag) const {return mStack.LastOf(aTag);}
void Empty(void);
int32_t GetCount(void) const {return mStack.mCount;}
int32_t GetResidualStyleCount(void) {return mResidualStyleCount;}
nsEntryStack* GetStylesAt(int32_t anIndex) const;
void PushStyle(nsCParserNode* aNode);
void PushStyles(nsEntryStack *aStyles);
nsCParserNode* PopStyle(void);
nsCParserNode* PopStyle(eHTMLTags aTag);
void RemoveStyle(eHTMLTags aTag);
static void ReleaseGlobalObjects(void);
void SetTokenAllocator(nsTokenAllocator* aTokenAllocator) { mTokenAllocator=aTokenAllocator; }
void SetNodeAllocator(nsNodeAllocator* aNodeAllocator) { mNodeAllocator=aNodeAllocator; }
nsEntryStack mStack; //this will hold a list of tagentries...
int32_t mResidualStyleCount;
int32_t mContextTopIndex;
nsTokenAllocator *mTokenAllocator;
nsNodeAllocator *mNodeAllocator;
#ifdef DEBUG
enum { eMaxTags = MAX_REFLOW_DEPTH };
eHTMLTags mXTags[eMaxTags];
#endif
};
/**************************************************************
Now define the token deallocator class...
**************************************************************/
class CTokenDeallocator: public nsDequeFunctor{
protected:
nsDummyAllocator& mArenaPool;
public:
CTokenDeallocator(nsDummyAllocator& aArenaPool)
: mArenaPool(aArenaPool) {}
virtual void* operator()(void* anObject) {
CToken* aToken = (CToken*)anObject;
aToken->Release(mArenaPool);
return 0;
}
};
/************************************************************************
ITagHandler class offers an API for taking care of specific tokens.
************************************************************************/
class nsITagHandler {
public:
virtual void SetString(const nsString &aTheString)=0;
virtual nsString* GetString()=0;
virtual bool HandleToken(CToken* aToken,nsIDTD* aDTD)=0;
virtual bool HandleCapturedTokens(CToken* aToken,nsIDTD* aDTD)=0;
};
/************************************************************************
Here are a few useful utility methods...
************************************************************************/
/**
* This method quickly scans the given set of tags,
* looking for the given tag.
* @update gess8/27/98
* @param aTag -- tag to be search for in set
* @param aTagSet -- set of tags to be searched
* @return
*/
inline int32_t IndexOfTagInSet(int32_t aTag,const eHTMLTags* aTagSet,int32_t aCount) {
const eHTMLTags* theEnd=aTagSet+aCount;
const eHTMLTags* theTag=aTagSet;
while(theTag<theEnd) {
if(aTag==*theTag) {
return theTag-aTagSet;
}
++theTag;
}
return kNotFound;
}
/**
* This method quickly scans the given set of tags,
* looking for the given tag.
* @update gess8/27/98
* @param aTag -- tag to be search for in set
* @param aTagSet -- set of tags to be searched
* @return
*/
inline bool FindTagInSet(int32_t aTag,const eHTMLTags *aTagSet,int32_t aCount) {
return bool(-1<IndexOfTagInSet(aTag,aTagSet,aCount));
}
/*********************************************************************************************/
struct TagList {
size_t mCount;
const eHTMLTags *mTags;
};
/**
* Find the last member of given taglist on the given context
* @update gess 12/14/99
* @param aContext
* @param aTagList
* @return index of tag, or kNotFound if not found
*/
inline int32_t LastOf(nsDTDContext& aContext, const TagList& aTagList){
int max = aContext.GetCount();
int index;
for(index=max-1;index>=0;index--){
bool result=FindTagInSet(aContext[index],aTagList.mTags,aTagList.mCount);
if(result) {
return index;
}
}
return kNotFound;
}
/**
* Find the first member of given taglist on the given context
* @update gess 12/14/99
* @param aContext
* @param aStartOffset
* @param aTagList
* @return index of tag, or kNotFound if not found
*/
inline int32_t FirstOf(nsDTDContext& aContext,int32_t aStartOffset,TagList& aTagList){
int max = aContext.GetCount();
int index;
for(index=aStartOffset;index<max;++index){
bool result=FindTagInSet(aContext[index],aTagList.mTags,aTagList.mCount);
if(result) {
return index;
}
}
return kNotFound;
}
/**
* Call this to find out whether the DTD thinks the tag requires an END tag </xxx>
* @update gess 01/04/99
* @param id of tag
* @return TRUE of the element's end tag is optional
*/
inline bool HasOptionalEndTag(eHTMLTags aTag) {
static eHTMLTags gHasOptionalEndTags[]={eHTMLTag_body,eHTMLTag_colgroup,eHTMLTag_dd,eHTMLTag_dt,
eHTMLTag_head,eHTMLTag_li,eHTMLTag_option,
eHTMLTag_p,eHTMLTag_tbody,eHTMLTag_td,eHTMLTag_tfoot,
eHTMLTag_th,eHTMLTag_thead,eHTMLTag_tr,
eHTMLTag_userdefined,eHTMLTag_unknown};
return FindTagInSet(aTag,gHasOptionalEndTags,sizeof(gHasOptionalEndTags)/sizeof(eHTMLTag_body));
}
#endif

File diff suppressed because it is too large Load Diff

View File

@ -15,9 +15,8 @@
#ifndef _NSELEMENTABLE
#define _NSELEMENTABLE
#include "nsHTMLTokens.h"
#include "nsDTDUtils.h"
#include "nsHTMLTags.h"
#include "nsIDTD.h"
//*********************************************************************************************
// The following ints define the standard groups of HTML elements...
@ -59,7 +58,6 @@ static const int kAllTags = 0xffffff;
// The following ints define the standard groups of HTML elements...
//*********************************************************************************************
#ifdef DEBUG
extern void CheckElementTable();
#endif
@ -68,7 +66,6 @@ extern void CheckElementTable();
/**
* We're asking the question: is aTest a member of bitset.
*
* @update gess 01/04/99
* @param
* @return TRUE or FALSE
*/
@ -80,158 +77,16 @@ inline bool TestBits(int aBitset,int aTest) {
return false;
}
/**
*
* @update gess 01/04/99
* @param
* @return
*/
struct nsHTMLElement {
#ifdef DEBUG
static void DebugDumpMembership(const char* aFilename);
static void DebugDumpContainment(const char* aFilename,const char* aTitle);
static void DebugDumpContainType(const char* aFilename);
#endif
static bool IsInlineEntity(eHTMLTags aTag);
static bool IsFlowEntity(eHTMLTags aTag);
static bool IsBlockCloser(eHTMLTags aTag);
inline bool IsBlock(void) const {
if((mTagID>=eHTMLTag_unknown) & (mTagID<=eHTMLTag_xmp)){
return TestBits(mParentBits,kBlock);
}
return false;
}
inline bool IsBlockEntity(void) const {
if((mTagID>=eHTMLTag_unknown) & (mTagID<=eHTMLTag_xmp)){
return TestBits(mParentBits,kBlockEntity);
}
return false;
}
inline bool IsSpecialEntity(void) const {
if((mTagID>=eHTMLTag_unknown) & (mTagID<=eHTMLTag_xmp)){
return TestBits(mParentBits,kSpecial);
}
return false;
}
inline bool IsPhraseEntity(void) const {
if((mTagID>=eHTMLTag_unknown) & (mTagID<=eHTMLTag_xmp)){
return TestBits(mParentBits,kPhrase);
}
return false;
}
inline bool IsFontStyleEntity(void) const {
if((mTagID>=eHTMLTag_unknown) & (mTagID<=eHTMLTag_xmp)){
return TestBits(mParentBits,kFontStyle);
}
return false;
}
inline bool IsTableElement(void) const { //return yes if it's a table or child of a table...
bool result=false;
switch(mTagID) {
case eHTMLTag_table:
case eHTMLTag_thead:
case eHTMLTag_tbody:
case eHTMLTag_tfoot:
case eHTMLTag_caption:
case eHTMLTag_tr:
case eHTMLTag_td:
case eHTMLTag_th:
case eHTMLTag_col:
case eHTMLTag_colgroup:
result=true;
break;
default:
result=false;
}
return result;
}
static int32_t GetIndexOfChildOrSynonym(nsDTDContext& aContext,eHTMLTags aChildTag);
const TagList* GetSynonymousTags(void) const {return mSynonymousTags;}
const TagList* GetRootTags(void) const {return mRootNodes;}
const TagList* GetEndRootTags(void) const {return mEndRootNodes;}
const TagList* GetAutoCloseStartTags(void) const {return mAutocloseStart;}
const TagList* GetAutoCloseEndTags(void) const {return mAutocloseEnd;}
eHTMLTags GetCloseTargetForEndTag(nsDTDContext& aContext,int32_t anIndex,nsDTDMode aMode) const;
const TagList* GetSpecialChildren(void) const {return mSpecialKids;}
const TagList* GetSpecialParents(void) const {return mSpecialParents;}
bool IsMemberOf(int32_t aType) const;
bool ContainsSet(int32_t aType) const;
bool CanContainType(int32_t aType) const;
bool CanContain(eHTMLTags aChild,nsDTDMode aMode) const;
bool CanExclude(eHTMLTags aChild) const;
bool CanOmitEndTag(void) const;
bool CanContainSelf(void) const;
bool CanAutoCloseTag(nsDTDContext& aContext,int32_t aIndex,eHTMLTags aTag) const;
bool HasSpecialProperty(int32_t aProperty) const;
bool IsSpecialParent(eHTMLTags aTag) const;
bool IsExcludableParent(eHTMLTags aParent) const;
bool SectionContains(eHTMLTags aTag,bool allowDepthSearch) const;
bool ShouldVerifyHierarchy() const;
static bool CanContain(eHTMLTags aParent,eHTMLTags aChild,nsDTDMode aMode);
static bool IsContainer(eHTMLTags aTag) ;
static bool IsResidualStyleTag(eHTMLTags aTag) ;
static bool IsTextTag(eHTMLTags aTag);
static bool IsWhitespaceTag(eHTMLTags aTag);
static bool IsBlockParent(eHTMLTags aTag);
static bool IsInlineParent(eHTMLTags aTag);
static bool IsFlowParent(eHTMLTags aTag);
static bool IsSectionTag(eHTMLTags aTag);
static bool IsChildOfHead(eHTMLTags aTag,bool& aExclusively) ;
eHTMLTags mTagID;
eHTMLTags mRequiredAncestor;
eHTMLTags mExcludingAncestor; //If set, the presence of the excl-ancestor prevents this from opening.
const TagList* mRootNodes; //These are the tags above which you many not autoclose a START tag
const TagList* mEndRootNodes; //These are the tags above which you many not autoclose an END tag
const TagList* mAutocloseStart; //these are the start tags that you can automatically close with this START tag
const TagList* mAutocloseEnd; //these are the start tags that you can automatically close with this END tag
const TagList* mSynonymousTags; //These are morally equivalent; an end tag for one can close a start tag for another (like <Hn>)
const TagList* mExcludableParents; //These are the TAGS that cannot contain you
int mParentBits; //defines groups that can contain this element
int mInclusionBits; //defines parental and containment rules
int mExclusionBits; //defines things you CANNOT contain
int mSpecialProperties; //used for various special purposes...
uint32_t mPropagateRange; //tells us how far a parent is willing to prop. badly formed children
const TagList* mSpecialParents; //These are the special tags that contain this tag (directly)
const TagList* mSpecialKids; //These are the extra things you can contain
bool mLeaf;
static bool IsContainer(eHTMLTags aTag);
};
extern const nsHTMLElement gHTMLElements[];
//special property bits...
static const int kPreferBody = 0x0001; //this kHeadMisc tag prefers to be in the body if there isn't an explicit <head>
static const int kOmitEndTag = 0x0002; //safely ignore end tag
static const int kLegalOpen = 0x0004; //Lets BODY, TITLE, SCRIPT to reopen
static const int kNoPropagate = 0x0008; //If set, this tag won't propagate as a child
static const int kBadContentWatch = 0x0010;
static const int kNoStyleLeaksIn = 0x0020;
static const int kNoStyleLeaksOut = 0x0040;
static const int kMustCloseSelf = 0x0080;
static const int kSaveMisplaced = 0x0100; //If set, then children this tag can't contain are pushed onto the misplaced stack
static const int kNonContainer = 0x0200; //If set, then this tag is not a container.
static const int kHandleStrayTag = 0x0400; //If set, we automatically open a start tag
static const int kRequiresBody = 0x0800; //If set, then in case of no BODY one will be opened up immediately.
static const int kVerifyHierarchy = 0x1000; //If set, check to see if the tag is a child or a sibling..
static const int kPreferHead = 0x2000; //This kHeadMisc tag prefers to be in the head if there isn't an explicit <body>
#endif

View File

@ -1289,9 +1289,7 @@ nsExpatDriver::WillBuildModel(const CParserContext& aParserContext,
}
NS_IMETHODIMP
nsExpatDriver::BuildModel(nsITokenizer* aTokenizer,
bool,// aCountLines,
const nsCString*)// aCharsetPtr)
nsExpatDriver::BuildModel(nsITokenizer* aTokenizer, nsIContentSink* aSink)
{
return mInternalState;
}
@ -1306,19 +1304,12 @@ nsExpatDriver::DidBuildModel(nsresult anErrorCode)
}
NS_IMETHODIMP
nsExpatDriver::WillTokenize(bool aIsFinalChunk,
nsTokenAllocator* aTokenAllocator)
nsExpatDriver::WillTokenize(bool aIsFinalChunk)
{
mIsFinalChunk = aIsFinalChunk;
return NS_OK;
}
NS_IMETHODIMP
nsExpatDriver::DidTokenize(bool aIsFinalChunk)
{
return NS_OK;
}
NS_IMETHODIMP_(void)
nsExpatDriver::Terminate()
{
@ -1343,65 +1334,6 @@ nsExpatDriver::GetMode() const
/*************************** Unused methods **********************************/
NS_IMETHODIMP_(CToken*)
nsExpatDriver::PushTokenFront(CToken* aToken)
{
return 0;
}
NS_IMETHODIMP_(CToken*)
nsExpatDriver::PushToken(CToken* aToken)
{
return 0;
}
NS_IMETHODIMP_(CToken*)
nsExpatDriver::PopToken(void)
{
return 0;
}
NS_IMETHODIMP_(CToken*)
nsExpatDriver::PeekToken(void)
{
return 0;
}
NS_IMETHODIMP_(CToken*)
nsExpatDriver::GetTokenAt(int32_t anIndex)
{
return 0;
}
NS_IMETHODIMP_(int32_t)
nsExpatDriver::GetCount(void)
{
return 0;
}
NS_IMETHODIMP_(nsTokenAllocator*)
nsExpatDriver::GetTokenAllocator(void)
{
return 0;
}
NS_IMETHODIMP_(void)
nsExpatDriver::PrependTokens(nsDeque& aDeque)
{
}
NS_IMETHODIMP
nsExpatDriver::CopyState(nsITokenizer* aTokenizer)
{
return NS_OK;
}
nsresult
nsExpatDriver::HandleToken(CToken* aToken)
{
return NS_OK;
}
NS_IMETHODIMP_(bool)
nsExpatDriver::IsContainer(int32_t aTag) const
{

View File

@ -67,8 +67,6 @@ public:
const PRUnichar* aNotationName);
private:
nsresult HandleToken(CToken* aToken);
// Load up an external stream to get external entity information
nsresult OpenInputStreamFromExternalDTD(const PRUnichar* aFPIStr,
const PRUnichar* aURLStr,

File diff suppressed because it is too large Load Diff

View File

@ -19,12 +19,6 @@
#include "prtypes.h"
#include "nsDeque.h"
#include "nsScanner.h"
#include "nsHTMLTokens.h"
#include "nsDTDUtils.h"
/***************************************************************
Notes:
***************************************************************/
#ifdef _MSC_VER
#pragma warning( disable : 4275 )
@ -42,33 +36,6 @@ public:
virtual ~nsHTMLTokenizer();
static uint32_t GetFlags(const nsIContentSink* aSink);
protected:
nsresult ConsumeTag(PRUnichar aChar,CToken*& aToken,nsScanner& aScanner,bool& aFlushTokens);
nsresult ConsumeStartTag(PRUnichar aChar,CToken*& aToken,nsScanner& aScanner,bool& aFlushTokens);
nsresult ConsumeEndTag(PRUnichar aChar,CToken*& aToken,nsScanner& aScanner);
nsresult ConsumeAttributes(PRUnichar aChar, CToken* aToken, nsScanner& aScanner);
nsresult ConsumeEntity(PRUnichar aChar,CToken*& aToken,nsScanner& aScanner);
nsresult ConsumeWhitespace(PRUnichar aChar,CToken*& aToken,nsScanner& aScanner);
nsresult ConsumeComment(PRUnichar aChar,CToken*& aToken,nsScanner& aScanner);
nsresult ConsumeNewline(PRUnichar aChar,CToken*& aToken,nsScanner& aScanner);
nsresult ConsumeText(CToken*& aToken,nsScanner& aScanner);
nsresult ConsumeSpecialMarkup(PRUnichar aChar,CToken*& aToken,nsScanner& aScanner);
nsresult ConsumeProcessingInstruction(PRUnichar aChar,CToken*& aToken,nsScanner& aScanner);
nsresult ScanDocStructure(bool aIsFinalChunk);
static void AddToken(CToken*& aToken,nsresult aResult,nsDeque* aDeque,nsTokenAllocator* aTokenAllocator);
nsDeque mTokenDeque;
bool mIsFinalChunk;
nsTokenAllocator* mTokenAllocator;
// This variable saves the position of the last tag we inspected in
// ScanDocStructure. We start scanning the general well-formedness of the
// document starting at this position each time.
int32_t mTokenScanPos;
uint32_t mFlags;
};
#endif

File diff suppressed because it is too large Load Diff

View File

@ -40,6 +40,8 @@
#include "nsParserConstants.h"
#include "nsCharsetSource.h"
#include "nsContentUtils.h"
#include "nsThreadUtils.h"
#include "nsIHTMLContentSink.h"
#include "mozilla/dom/EncodingUtils.h"
@ -1009,12 +1011,6 @@ nsParser::PopContext()
if (mParserContext->mStreamListenerState != eOnStop) {
mParserContext->mStreamListenerState = oldContext->mStreamListenerState;
}
// Update the current context's tokenizer to any information gleaned
// while parsing document.write() calls (such as "a plaintext tag was
// found")
if (mParserContext->mTokenizer) {
mParserContext->mTokenizer->CopyState(oldContext->mTokenizer);
}
}
}
return oldContext;
@ -1619,11 +1615,7 @@ nsParser::BuildModel()
if (NS_SUCCEEDED(result)) {
if (mDTD) {
bool inDocWrite = !!mParserContext->mPrevContext;
result = mDTD->BuildModel(theTokenizer,
// ignore interruptions in document.write
!inDocWrite, // don't count lines in document.write
&mCharset);
result = mDTD->BuildModel(theTokenizer, mSink);
}
} else {
mInternalState = result = NS_ERROR_HTMLPARSER_BADTOKENIZER;
@ -1994,8 +1986,7 @@ nsParser::WillTokenize(bool aIsFinalChunk)
nsITokenizer* theTokenizer;
nsresult result = mParserContext->GetTokenizer(mDTD, mSink, theTokenizer);
NS_ENSURE_SUCCESS(result, false);
return NS_SUCCEEDED(theTokenizer->WillTokenize(aIsFinalChunk,
&mTokenAllocator));
return NS_SUCCEEDED(theTokenizer->WillTokenize(aIsFinalChunk));
}
@ -2014,18 +2005,6 @@ nsresult nsParser::Tokenize(bool aIsFinalChunk)
}
if (NS_SUCCEEDED(result)) {
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) {
return result;
}
// Reset since the tokens have been flushed.
mFlags &= ~NS_PARSER_FLAG_FLUSH_TOKENS;
}
bool flushTokens = false;
mParserContext->mNumConsumed = 0;
@ -2056,7 +2035,6 @@ nsresult nsParser::Tokenize(bool aIsFinalChunk)
break;
}
}
DidTokenize(aIsFinalChunk);
if (killSink) {
mSink = nullptr;
@ -2068,26 +2046,6 @@ nsresult nsParser::Tokenize(bool aIsFinalChunk)
return result;
}
/**
* This is the tail-end of the code sandwich for the
* tokenization process. It gets called once tokenziation
* has completed for each phase.
*/
bool
nsParser::DidTokenize(bool aIsFinalChunk)
{
if (!mParserContext) {
return true;
}
nsITokenizer* theTokenizer;
nsresult rv = mParserContext->GetTokenizer(mDTD, mSink, theTokenizer);
NS_ENSURE_SUCCESS(rv, false);
rv = theTokenizer->DidTokenize(aIsFinalChunk);
return NS_SUCCEEDED(rv);
}
/**
* Get the channel associated with this parser
*

View File

@ -49,7 +49,6 @@
#include "nsParserCIID.h"
#include "nsITokenizer.h"
#include "nsHTMLTags.h"
#include "nsDTDUtils.h"
#include "nsIContentSink.h"
#include "nsCOMArray.h"
#include "nsCycleCollectionParticipant.h"
@ -58,6 +57,7 @@
class nsICharsetConverterManager;
class nsIDTD;
class nsScanner;
class nsIRunnable;
#ifdef _MSC_VER
#pragma warning( disable : 4275 )
@ -367,17 +367,6 @@ private:
*/
nsresult Tokenize(bool aIsFinalChunk = false);
/**
* This is the tail-end of the code sandwich for the
* tokenization process. It gets called once tokenziation
* has completed.
*
* @update gess 3/25/98
* @param
* @return TRUE if all went well
*/
bool DidTokenize(bool aIsFinalChunk = false);
/**
* Pushes XML fragment parsing data to expat without an input stream.
*/
@ -396,9 +385,7 @@ protected:
nsCOMPtr<nsIRequestObserver> mObserver;
nsCOMPtr<nsIContentSink> mSink;
nsIRunnable* mContinueEvent; // weak ref
nsTokenAllocator mTokenAllocator;
eParserCommands mCommand;
nsresult mInternalState;
nsresult mStreamStatus;

View File

@ -79,7 +79,6 @@ Initialize()
#ifdef DEBUG
CheckElementTable();
#endif
CNewlineToken::AllocNewline();
#ifdef DEBUG
nsHTMLTags::TestTagTable();
@ -93,9 +92,7 @@ Shutdown()
{
nsHTMLTags::ReleaseTable();
nsHTMLEntities::ReleaseTable();
nsDTDContext::ReleaseGlobalObjects();
nsParser::Shutdown();
CNewlineToken::FreeNewline();
}
static mozilla::Module kParserModule = {

View File

@ -4,26 +4,8 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "nsIAtom.h"
#include "nsParserNode.h"
#include <string.h>
#include "nsHTMLTokens.h"
#include "nsITokenizer.h"
#include "nsDTDUtils.h"
/**
* Default Constructor
*/
nsCParserNode::nsCParserNode()
: mRefCnt(0), mGenericState(false), mUseCount(0), mToken(nullptr),
mTokenAllocator(nullptr)
{
MOZ_COUNT_CTOR(nsCParserNode);
#ifdef HEAP_ALLOCATED_NODES
mNodeAllocator = nullptr;
#endif
}
#include "nsParserNode.h"
#include "nsToken.h"
/**
* Constructor
@ -32,23 +14,9 @@ nsCParserNode::nsCParserNode()
* @param aToken -- token to init internal token
* @return
*/
nsCParserNode::nsCParserNode(CToken* aToken,
nsTokenAllocator* aTokenAllocator,
nsNodeAllocator* aNodeAllocator)
: mRefCnt(0), mGenericState(false), mUseCount(0), mToken(aToken),
mTokenAllocator(aTokenAllocator)
nsParserNode::nsParserNode(eHTMLTags aTag)
: mTag(aTag)
{
MOZ_COUNT_CTOR(nsCParserNode);
static int theNodeCount = 0;
++theNodeCount;
if (mTokenAllocator) {
IF_HOLD(mToken);
} // Else a stack-based token
#ifdef HEAP_ALLOCATED_NODES
mNodeAllocator = aNodeAllocator;
#endif
}
/**
@ -59,81 +27,10 @@ nsCParserNode::nsCParserNode(CToken* aToken,
* @param
* @return
*/
nsCParserNode::~nsCParserNode() {
MOZ_COUNT_DTOR(nsCParserNode);
ReleaseAll();
#ifdef HEAP_ALLOCATED_NODES
if(mNodeAllocator) {
mNodeAllocator->Recycle(this);
}
mNodeAllocator = nullptr;
#endif
mTokenAllocator = 0;
nsParserNode::~nsParserNode() {
}
/**
* Init
*
* @update gess 3/25/98
* @param
* @return
*/
nsresult
nsCParserNode::Init(CToken* aToken,
nsTokenAllocator* aTokenAllocator,
nsNodeAllocator* aNodeAllocator)
{
mTokenAllocator = aTokenAllocator;
mToken = aToken;
if (mTokenAllocator) {
IF_HOLD(mToken);
} // Else a stack-based token
mGenericState = false;
mUseCount=0;
#ifdef HEAP_ALLOCATED_NODES
mNodeAllocator = aNodeAllocator;
#endif
return NS_OK;
}
void
nsCParserNode::AddAttribute(CToken* aToken)
{
}
/**
* Gets the name of this node. Currently unused.
*
* @update gess 3/25/98
* @param
* @return string ref containing node name
*/
const nsAString&
nsCParserNode::GetTagName() const {
return EmptyString();
}
/**
* 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 nsAString&
nsCParserNode::GetText() const
{
if (mToken) {
return mToken->GetStringValue();
}
return EmptyString();
}
/**
* Get node type, meaning, get the tag type of the
* underlying token
@ -143,9 +40,9 @@ nsCParserNode::GetText() const
* @return int value that represents tag type
*/
int32_t
nsCParserNode::GetNodeType(void) const
nsParserNode::GetNodeType(void) const
{
return (mToken) ? mToken->GetTypeID() : 0;
return mTag;
}
@ -158,9 +55,9 @@ nsCParserNode::GetNodeType(void) const
* @return
*/
int32_t
nsCParserNode::GetTokenType(void) const
nsParserNode::GetTokenType(void) const
{
return (mToken) ? mToken->GetTokenType() : 0;
return eToken_start;
}
@ -172,7 +69,7 @@ nsCParserNode::GetTokenType(void) const
* @return int -- representing attribute count
*/
int32_t
nsCParserNode::GetAttributeCount(bool askToken) const
nsParserNode::GetAttributeCount() const
{
return 0;
}
@ -186,12 +83,11 @@ nsCParserNode::GetAttributeCount(bool askToken) const
* @return string rep of given attribute text key
*/
const nsAString&
nsCParserNode::GetKeyAt(uint32_t anIndex) const
nsParserNode::GetKeyAt(uint32_t anIndex) const
{
return EmptyString();
}
/**
* Retrieve the string rep of the attribute at given offset
*
@ -200,171 +96,7 @@ nsCParserNode::GetKeyAt(uint32_t anIndex) const
* @return string rep of given attribute text value
*/
const nsAString&
nsCParserNode::GetValueAt(uint32_t anIndex) const
nsParserNode::GetValueAt(uint32_t anIndex) const
{
return EmptyString();
}
int32_t
nsCParserNode::TranslateToUnicodeStr(nsString& aString) const
{
if (eToken_entity == mToken->GetTokenType()) {
return ((CEntityToken*)mToken)->TranslateToUnicodeStr(aString);
}
return -1;
}
/**
* This getter retrieves the line number from the input source where
* the token occurred. Lines are interpreted as occurring between \n characters.
* @update gess7/24/98
* @return int containing the line number the token was found on
*/
int32_t
nsCParserNode::GetSourceLineNumber(void) const {
return mToken ? mToken->GetLineNumber() : 0;
}
/**
* This method pop the attribute token
* @update harishd 03/25/99
* @return token at anIndex
*/
CToken*
nsCParserNode::PopAttributeToken() {
return 0;
}
CToken*
nsCParserNode::PopAttributeTokenFront() {
return 0;
}
/** Retrieve a string containing the tag and its attributes in "source" form
* @update rickg 06June2000
* @return void
*/
void
nsCParserNode::GetSource(nsString& aString) const
{
eHTMLTags theTag = mToken ? (eHTMLTags)mToken->GetTypeID() : eHTMLTag_unknown;
aString.Assign(PRUnichar('<'));
const PRUnichar* theTagName = nsHTMLTags::GetStringValue(theTag);
if(theTagName) {
aString.Append(theTagName);
}
aString.Append(PRUnichar('>'));
}
/** Release all the objects you're holding to.
* @update harishd 08/02/00
* @return void
*/
nsresult
nsCParserNode::ReleaseAll()
{
if(mTokenAllocator) {
IF_FREE(mToken,mTokenAllocator);
}
return NS_OK;
}
nsresult
nsCParserStartNode::Init(CToken* aToken,
nsTokenAllocator* aTokenAllocator,
nsNodeAllocator* aNodeAllocator)
{
NS_ASSERTION(mAttributes.GetSize() == 0, "attributes not recycled!");
return nsCParserNode::Init(aToken, aTokenAllocator, aNodeAllocator);
}
void nsCParserStartNode::AddAttribute(CToken* aToken)
{
NS_ASSERTION(0 != aToken, "Error: Token shouldn't be null!");
mAttributes.Push(aToken);
}
int32_t
nsCParserStartNode::GetAttributeCount(bool askToken) const
{
int32_t result = 0;
if (askToken) {
result = mToken ? mToken->GetAttributeCount() : 0;
}
else {
result = mAttributes.GetSize();
}
return result;
}
const nsAString&
nsCParserStartNode::GetKeyAt(uint32_t anIndex) const
{
if ((int32_t)anIndex < mAttributes.GetSize()) {
CAttributeToken* attr =
static_cast<CAttributeToken*>(mAttributes.ObjectAt(anIndex));
if (attr) {
return attr->GetKey();
}
}
return EmptyString();
}
const nsAString&
nsCParserStartNode::GetValueAt(uint32_t anIndex) const
{
if (int32_t(anIndex) < mAttributes.GetSize()) {
CAttributeToken* attr =
static_cast<CAttributeToken*>(mAttributes.ObjectAt(anIndex));
if (attr) {
return attr->GetValue();
}
}
return EmptyString();
}
CToken*
nsCParserStartNode::PopAttributeToken()
{
return static_cast<CToken*>(mAttributes.Pop());
}
CToken*
nsCParserStartNode::PopAttributeTokenFront()
{
return static_cast<CToken*>(mAttributes.PopFront());
}
void nsCParserStartNode::GetSource(nsString& aString) const
{
aString.Assign(PRUnichar('<'));
const PRUnichar* theTagName =
nsHTMLTags::GetStringValue(nsHTMLTag(mToken->GetTypeID()));
if (theTagName) {
aString.Append(theTagName);
}
int32_t index;
int32_t size = mAttributes.GetSize();
for (index = 0 ; index < size; ++index) {
CAttributeToken *theToken =
static_cast<CAttributeToken*>(mAttributes.ObjectAt(index));
if (theToken) {
theToken->AppendSourceTo(aString);
aString.Append(PRUnichar(' ')); //this will get removed...
}
}
aString.Append(PRUnichar('>'));
}
nsresult nsCParserStartNode::ReleaseAll()
{
NS_ASSERTION(0!=mTokenAllocator, "Error: no token allocator");
CToken* theAttrToken;
while ((theAttrToken = static_cast<CToken*>(mAttributes.Pop()))) {
IF_FREE(theAttrToken, mTokenAllocator);
}
nsCParserNode::ReleaseAll();
return NS_OK;
}

View File

@ -3,147 +3,34 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/**
* MODULE NOTES:
* @update gess 4/1/98
*
* This class is defines the basic interface between the
* parser and the content sink. The parser will iterate
* over the collection of tokens that it sees from the
* tokenizer, coverting each related "group" into one of
* these. This object gets passed to the sink, and is
* then immediately reused.
*
* If you want to hang onto one of these, you should
* make your own copy.
*
*/
#ifndef NS_PARSERNODE__
#define NS_PARSERNODE__
#include "nscore.h"
#include "nsIParserNode.h"
#include "nsToken.h"
#include "nsString.h"
#include "nsParserCIID.h"
#include "nsDeque.h"
#include "nsDTDUtils.h"
class nsTokenAllocator;
class nsCParserNode : public nsIParserNode {
protected:
int32_t mRefCnt;
#include "nsHTMLTags.h"
class nsParserNode : public nsIParserNode
{
public:
void AddRef()
{
++mRefCnt;
}
void Release(nsDummyAllocator& aPool)
{
if (--mRefCnt == 0)
Destroy(this, aPool);
}
#ifndef HEAP_ALLOCATED_NODES
protected:
/**
* Hide operator new; clients should use Create() instead.
*/
static void* operator new(size_t) CPP_THROW_NEW { return 0; }
/**
* Hide operator delete; clients should use Destroy() instead.
*/
static void operator delete(void*,size_t) {}
#endif
public:
static nsCParserNode* Create(CToken* aToken,
nsTokenAllocator* aTokenAllocator,
nsNodeAllocator* aNodeAllocator)
{
#ifdef HEAP_ALLOCATED_NODES
return new
#else
nsDummyAllocator& pool = aNodeAllocator->GetArenaPool();
void* place = pool.Alloc(sizeof(nsCParserNode));
NS_ENSURE_TRUE(place, nullptr);
return ::new (place)
#endif
nsCParserNode(aToken, aTokenAllocator, aNodeAllocator);
}
static void Destroy(nsCParserNode* aNode, nsDummyAllocator& aPool)
{
#ifdef HEAP_ALLOCATED_NODES
delete aNode;
#else
aNode->~nsCParserNode();
aPool.Free(aNode);
#endif
}
/**
* Default constructor
*/
nsCParserNode();
/**
* Constructor
* @update gess5/11/98
* @param aToken is the token this node "refers" to
*/
nsCParserNode(CToken* aToken,
nsTokenAllocator* aTokenAllocator,
nsNodeAllocator* aNodeAllocator=0);
nsParserNode(eHTMLTags aTag);
/**
* Destructor
* @update gess5/11/98
*/
virtual ~nsCParserNode();
/**
* Init
* @update gess5/11/98
*/
virtual nsresult Init(CToken* aToken,
nsTokenAllocator* aTokenAllocator,
nsNodeAllocator* aNodeAllocator=0);
/**
* Retrieve the name of the node
* @update gess5/11/98
* @return string containing node name
*/
virtual const nsAString& GetTagName() const;
/**
* Retrieve the text from the given node
* @update gess5/11/98
* @return string containing node text
*/
virtual const nsAString& GetText() const;
virtual ~nsParserNode();
/**
* Retrieve the type of the parser node.
* @update gess5/11/98
* @return node type.
*/
virtual int32_t GetNodeType() const;
/**
* Retrieve token type of parser node
* @update gess5/11/98
* @return token type
*/
virtual int32_t GetTokenType() const;
@ -155,14 +42,12 @@ class nsCParserNode : public nsIParserNode {
/**
* Retrieve the number of attributes in this node.
* @update gess5/11/98
* @return count of attributes (may be 0)
* @return 0
*/
virtual int32_t GetAttributeCount(bool askToken=false) const;
virtual int32_t GetAttributeCount() const;
/**
* Retrieve the key (of key/value pair) at given index
* @update gess5/11/98
* @param anIndex is the index of the key you want
* @return string containing key.
*/
@ -176,121 +61,8 @@ class nsCParserNode : public nsIParserNode {
*/
virtual const nsAString& GetValueAt(uint32_t anIndex) const;
/**
* NOTE: When the node is an entity, this will translate the entity
* to it's unicode value, and store it in aString.
* @update gess5/11/98
* @param aString will contain the resulting unicode string value
* @return int (unicode char or unicode index from table)
*/
virtual int32_t TranslateToUnicodeStr(nsString& aString) const;
/**
*
* @update gess5/11/98
* @param
* @return
*/
virtual void AddAttribute(CToken* aToken);
/**
* This getter retrieves the line number from the input source where
* the token occurred. Lines are interpreted as occurring between \n characters.
* @update gess7/24/98
* @return int containing the line number the token was found on
*/
virtual int32_t GetSourceLineNumber(void) const;
/** This method pop the attribute token from the given index
* @update harishd 03/25/99
* @return token at anIndex
*/
virtual CToken* PopAttributeToken();
/** Like PopAttributeToken, but pops off the front of the attribute list */
virtual CToken* PopAttributeTokenFront();
/** Retrieve a string containing the tag and its attributes in "source" form
* @update rickg 06June2000
* @return void
*/
virtual void GetSource(nsString& aString) const;
/**
* This pair of methods allows us to set a generic bit (for arbitrary use)
* on each node stored in the context.
* @update gess 11May2000
*/
virtual bool GetGenericState(void) const {return mGenericState;}
virtual void SetGenericState(bool aState) {mGenericState=aState;}
/** Release all the objects you're holding
* @update harishd 08/02/00
* @return void
*/
virtual nsresult ReleaseAll();
bool mGenericState;
int32_t mUseCount;
CToken* mToken;
nsTokenAllocator* mTokenAllocator;
#ifdef HEAP_ALLOCATED_NODES
nsNodeAllocator* mNodeAllocator; // weak
#endif
};
class nsCParserStartNode : public nsCParserNode
{
public:
static nsCParserNode* Create(CToken* aToken,
nsTokenAllocator* aTokenAllocator,
nsNodeAllocator* aNodeAllocator)
{
#ifdef HEAP_ALLOCATED_NODES
return new
#else
nsDummyAllocator& pool = aNodeAllocator->GetArenaPool();
void* place = pool.Alloc(sizeof(nsCParserStartNode));
NS_ENSURE_TRUE(place, nullptr);
return ::new (place)
#endif
nsCParserStartNode(aToken, aTokenAllocator, aNodeAllocator);
}
nsCParserStartNode()
: nsCParserNode(), mAttributes(0) { }
nsCParserStartNode(CToken* aToken,
nsTokenAllocator* aTokenAllocator,
nsNodeAllocator* aNodeAllocator = 0)
: nsCParserNode(aToken, aTokenAllocator, aNodeAllocator), mAttributes(0) { }
virtual ~nsCParserStartNode()
{
NS_ASSERTION(mTokenAllocator || mAttributes.GetSize() == 0,
"Error: no token allocator");
CToken* theAttrToken = 0;
while ((theAttrToken = static_cast<CToken*>(mAttributes.Pop()))) {
IF_FREE(theAttrToken, mTokenAllocator);
}
}
virtual nsresult Init(CToken* aToken,
nsTokenAllocator* aTokenAllocator,
nsNodeAllocator* aNodeAllocator = 0);
virtual void AddAttribute(CToken* aToken);
virtual int32_t GetAttributeCount(bool askToken = false) const;
virtual const nsAString& GetKeyAt(uint32_t anIndex) const;
virtual const nsAString& GetValueAt(uint32_t anIndex) const;
virtual CToken* PopAttributeToken();
virtual CToken* PopAttributeTokenFront();
virtual void GetSource(nsString& aString) const;
virtual nsresult ReleaseAll();
protected:
nsDeque mAttributes;
private:
eHTMLTags mTag;
};
#endif

View File

@ -7,7 +7,6 @@
#define NS_PARSERSERVICE_H__
#include "nsIParserService.h"
#include "nsDTDUtils.h"
extern "C" int MOZ_XMLIsLetter(const char* ptr);
extern "C" int MOZ_XMLIsNCNameChar(const char* ptr);

View File

@ -1,137 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "nsToken.h"
#include "nsScanner.h"
static int TokenCount=0;
static int DelTokenCount=0;
int CToken::GetTokenCount() {
return TokenCount-DelTokenCount;
}
/**************************************************************
And now for the CToken...
**************************************************************/
/**
* Default constructor
*
* @update gess 7/21/98
*/
CToken::CToken(int32_t aTag) {
mAttrCount=0;
mNewlineCount=0;
mLineNumber = 0;
mInError = false;
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
// use and therefore does not require an explicit addref, or
// rather IF_HOLD. This, also, will make sure that tokens created
// on the stack do not accidently hit the arena recycler.
mUseCount=1;
NS_LOG_ADDREF(this, 1, "CToken", sizeof(*this));
#ifdef DEBUG
++TokenCount;
#endif
}
/**
* Decstructor
*
* @update gess 3/25/98
*/
CToken::~CToken() {
++DelTokenCount;
#ifdef NS_BUILD_REFCNT_LOGGING
if (mUseCount == 1) {
// Stack token
NS_LOG_RELEASE(this, 0, "CToken");
}
#endif
mUseCount=0;
}
/**
* Virtual method used to tell this toke to consume his
* valid chars.
*
* @update gess 3/25/98
* @param aChar -- first char in sequence
* @param aScanner -- object to retrieve data from
* @return int error code
*/
nsresult CToken::Consume(PRUnichar aChar,nsScanner& aScanner,int32_t aMode) {
nsresult result=NS_OK;
return result;
}
/**
* Get string of full contents, suitable for debug dump.
* It should look exactly like the input source.
* @update gess5/11/98
* @return reference to string containing string value
*/
void CToken::GetSource(nsString& anOutputString) {
anOutputString.Assign(GetStringValue());
}
/**
* @update harishd 3/23/00
* @return reference to string containing string value
*/
void CToken::AppendSourceTo(nsAString& anOutputString) {
anOutputString.Append(GetStringValue());
}
/**
* Retrieves copy of internal ordinal value.
* This method is deprecated, and will soon be going away.
*
* @update gess 3/25/98
* @return int containing ordinal value
*/
int32_t CToken::GetTypeID(void) {
return mTypeID;
}
/**
* Retrieves copy of attr count for this token
*
* @update gess 3/25/98
* @return int containing attribute count
*/
int16_t CToken::GetAttributeCount(void) {
return mAttrCount;
}
/**
* Retrieve type of token. This class returns -1, but
* subclasses return something more meaningful.
*
* @update gess 3/25/98
* @return int value containing token type.
*/
int32_t CToken::GetTokenType(void) {
return -1;
}
/**
*
* @update gess 3/25/98
*/
void CToken::SelfTest(void) {
#ifdef _DEBUG
#endif
}