mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
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:
parent
3aed4aaa4c
commit
5c3a529f78
@ -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:
|
||||
|
@ -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
|
||||
|
@ -14,7 +14,6 @@ MODULE = 'htmlparser'
|
||||
EXPORTS += [
|
||||
'nsHTMLTagList.h',
|
||||
'nsHTMLTags.h',
|
||||
'nsHTMLTokens.h',
|
||||
'nsIContentSink.h',
|
||||
'nsIDTD.h',
|
||||
'nsIElementObserver.h',
|
||||
|
@ -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
|
@ -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();\
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
@ -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
|
||||
|
||||
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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'
|
||||
|
@ -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
|
@ -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
@ -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
|
||||
|
@ -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
|
||||
{
|
||||
|
@ -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
@ -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
@ -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
|
||||
*
|
||||
|
@ -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;
|
||||
|
@ -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 = {
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user