1998-04-14 00:24:54 +04:00
|
|
|
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
|
|
/*
|
1999-11-06 06:43:54 +03:00
|
|
|
* The contents of this file are subject to the Netscape Public
|
|
|
|
* License Version 1.1 (the "License"); you may not use this file
|
|
|
|
* except in compliance with the License. You may obtain a copy of
|
|
|
|
* the License at http://www.mozilla.org/NPL/
|
1998-04-14 00:24:54 +04:00
|
|
|
*
|
1999-11-06 06:43:54 +03:00
|
|
|
* Software distributed under the License is distributed on an "AS
|
|
|
|
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
|
|
|
* implied. See the License for the specific language governing
|
|
|
|
* rights and limitations under the License.
|
1998-04-14 00:24:54 +04:00
|
|
|
*
|
1999-11-06 06:43:54 +03:00
|
|
|
* The Original Code is mozilla.org code.
|
|
|
|
*
|
|
|
|
* The Initial Developer of the Original Code is Netscape
|
1998-04-14 00:24:54 +04:00
|
|
|
* Communications Corporation. Portions created by Netscape are
|
1999-11-06 06:43:54 +03:00
|
|
|
* Copyright (C) 1998 Netscape Communications Corporation. All
|
|
|
|
* Rights Reserved.
|
|
|
|
*
|
|
|
|
* Contributor(s):
|
1998-04-14 00:24:54 +04:00
|
|
|
*/
|
1998-05-22 00:38:32 +04:00
|
|
|
|
1998-04-14 00:24:54 +04:00
|
|
|
/**
|
|
|
|
* MODULE NOTES:
|
|
|
|
* @update gess 4/1/98
|
|
|
|
*
|
|
|
|
* This class does two primary jobs:
|
|
|
|
* 1) It iterates the tokens provided during the
|
|
|
|
* tokenization process, identifing where elements
|
|
|
|
* begin and end (doing validation and normalization).
|
|
|
|
* 2) It controls and coordinates with an instance of
|
|
|
|
* the IContentSink interface, to coordinate the
|
|
|
|
* the production of the content model.
|
|
|
|
*
|
|
|
|
* The basic operation of this class assumes that an HTML
|
|
|
|
* document is non-normalized. Therefore, we don't process
|
|
|
|
* the document in a normalized way. Don't bother to look
|
|
|
|
* for methods like: doHead() or doBody().
|
|
|
|
*
|
|
|
|
* Instead, in order to be backward compatible, we must
|
|
|
|
* scan the set of tokens and perform this basic set of
|
|
|
|
* operations:
|
|
|
|
* 1) Determine the token type (easy, since the tokens know)
|
|
|
|
* 2) Determine the appropriate section of the HTML document
|
|
|
|
* each token belongs in (HTML,HEAD,BODY,FRAMESET).
|
|
|
|
* 3) Insert content into our document (via the sink) into
|
|
|
|
* the correct section.
|
|
|
|
* 4) In the case of tags that belong in the BODY, we must
|
|
|
|
* ensure that our underlying document state reflects
|
|
|
|
* the appropriate context for our tag.
|
|
|
|
*
|
|
|
|
* For example,if we see a <TR>, we must ensure our
|
|
|
|
* document contains a table into which the row can
|
|
|
|
* be placed. This may result in "implicit containers"
|
|
|
|
* created to ensure a well-formed document.
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
1998-06-19 05:00:27 +04:00
|
|
|
#ifndef NS_PARSER__
|
|
|
|
#define NS_PARSER__
|
1998-04-14 00:24:54 +04:00
|
|
|
|
|
|
|
#include "nsIParser.h"
|
|
|
|
#include "nsDeque.h"
|
|
|
|
#include "nsParserNode.h"
|
1998-05-15 02:19:08 +04:00
|
|
|
#include "nsIURL.h"
|
1998-07-14 01:13:09 +04:00
|
|
|
#include "CParserContext.h"
|
1998-07-31 02:42:27 +04:00
|
|
|
#include "nsParserCIID.h"
|
1999-01-26 04:24:31 +03:00
|
|
|
#include "nsITokenizer.h"
|
1999-04-05 10:55:49 +04:00
|
|
|
#include "nsHTMLTags.h"
|
1999-07-17 01:07:54 +04:00
|
|
|
#include "nsDTDUtils.h"
|
1999-11-10 06:41:09 +03:00
|
|
|
#include "nsTimer.h"
|
1998-04-14 00:24:54 +04:00
|
|
|
|
|
|
|
class IContentSink;
|
1998-04-23 03:56:57 +04:00
|
|
|
class nsIDTD;
|
1999-01-09 04:09:02 +03:00
|
|
|
class nsScanner;
|
1998-06-19 02:57:25 +04:00
|
|
|
class nsIParserFilter;
|
1999-06-21 04:33:51 +04:00
|
|
|
class nsIProgressEventSink;
|
1999-05-16 09:27:23 +04:00
|
|
|
|
1999-04-05 10:55:49 +04:00
|
|
|
|
1998-07-28 08:16:13 +04:00
|
|
|
#include <fstream.h>
|
1998-04-14 00:24:54 +04:00
|
|
|
|
1999-07-22 21:44:19 +04:00
|
|
|
#ifdef XP_WIN
|
1999-01-26 04:24:31 +03:00
|
|
|
#pragma warning( disable : 4275 )
|
1999-02-04 01:58:49 +03:00
|
|
|
#endif
|
|
|
|
|
1999-01-26 04:24:31 +03:00
|
|
|
|
|
|
|
CLASS_EXPORT_HTMLPARS nsParser : public nsIParser, public nsIStreamListener {
|
1999-10-28 11:53:21 +04:00
|
|
|
|
|
|
|
|
1998-04-25 23:45:14 +04:00
|
|
|
public:
|
1999-10-28 11:53:21 +04:00
|
|
|
|
|
|
|
friend class CTokenHandler;
|
|
|
|
static void FreeSharedObjects(void);
|
1998-04-14 00:24:54 +04:00
|
|
|
|
|
|
|
NS_DECL_ISUPPORTS
|
1998-05-12 04:59:32 +04:00
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* default constructor
|
|
|
|
* @update gess5/11/98
|
|
|
|
*/
|
1999-01-26 04:24:31 +03:00
|
|
|
nsParser(nsITokenObserver* anObserver=0);
|
1998-05-12 04:59:32 +04:00
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Destructor
|
|
|
|
* @update gess5/11/98
|
|
|
|
*/
|
1998-07-14 01:42:45 +04:00
|
|
|
virtual ~nsParser();
|
1998-05-12 04:59:32 +04:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Select given content sink into parser for parser output
|
|
|
|
* @update gess5/11/98
|
|
|
|
* @param aSink is the new sink to be used by parser
|
|
|
|
* @return old sink, or NULL
|
|
|
|
*/
|
|
|
|
virtual nsIContentSink* SetContentSink(nsIContentSink* aSink);
|
1998-11-26 05:55:59 +03:00
|
|
|
|
|
|
|
/**
|
|
|
|
* retrive the sink set into the parser
|
|
|
|
* @update gess5/11/98
|
|
|
|
* @param aSink is the new sink to be used by parser
|
|
|
|
* @return old sink, or NULL
|
|
|
|
*/
|
|
|
|
virtual nsIContentSink* GetContentSink(void);
|
1998-06-18 03:13:28 +04:00
|
|
|
|
1998-11-11 14:55:32 +03:00
|
|
|
/**
|
|
|
|
* Call this method once you've created a parser, and want to instruct it
|
|
|
|
* about the command which caused the parser to be constructed. For example,
|
|
|
|
* this allows us to select a DTD which can do, say, view-source.
|
|
|
|
*
|
|
|
|
* @update gess 3/25/98
|
|
|
|
* @param aContentSink -- ptr to content sink that will receive output
|
|
|
|
* @return ptr to previously set contentsink (usually null)
|
|
|
|
*/
|
|
|
|
virtual void SetCommand(const char* aCommand);
|
|
|
|
|
1999-04-26 21:49:45 +04:00
|
|
|
/**
|
|
|
|
* Call this method once you've created a parser, and want to instruct it
|
|
|
|
* about what charset to load
|
|
|
|
*
|
|
|
|
* @update ftang 4/23/99
|
|
|
|
* @param aCharset- the charest of a document
|
|
|
|
* @param aCharsetSource- the soure of the chares
|
|
|
|
* @return nada
|
|
|
|
*/
|
|
|
|
virtual void SetDocumentCharset(nsString& aCharset, nsCharsetSource aSource);
|
|
|
|
|
1999-05-18 05:30:21 +04:00
|
|
|
void GetDocumentCharset(nsString& oCharset, nsCharsetSource& oSource)
|
|
|
|
{
|
|
|
|
oCharset = mCharset;
|
|
|
|
oSource = mCharsetSource;
|
|
|
|
}
|
|
|
|
|
1999-04-26 21:49:45 +04:00
|
|
|
|
1998-06-19 05:00:27 +04:00
|
|
|
virtual nsIParserFilter* SetParserFilter(nsIParserFilter* aFilter);
|
1998-06-18 03:13:28 +04:00
|
|
|
|
1998-07-02 12:14:22 +04:00
|
|
|
virtual void RegisterDTD(nsIDTD* aDTD);
|
|
|
|
|
1998-06-18 03:13:28 +04:00
|
|
|
/**
|
1998-08-12 12:53:55 +04:00
|
|
|
* Retrieve the scanner from the topmost parser context
|
1998-06-18 03:13:28 +04:00
|
|
|
*
|
1998-08-12 12:53:55 +04:00
|
|
|
* @update gess 6/9/98
|
|
|
|
* @return ptr to scanner
|
|
|
|
*/
|
|
|
|
virtual eParseMode GetParseMode(void);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Retrieve the scanner from the topmost parser context
|
1998-06-18 03:13:28 +04:00
|
|
|
*
|
|
|
|
* @update gess 6/9/98
|
1998-08-12 12:53:55 +04:00
|
|
|
* @return ptr to scanner
|
1998-06-18 03:13:28 +04:00
|
|
|
*/
|
1999-01-09 04:09:02 +03:00
|
|
|
virtual nsScanner* GetScanner(void);
|
1998-05-12 04:59:32 +04:00
|
|
|
|
|
|
|
/**
|
1998-07-14 01:13:09 +04:00
|
|
|
* Cause parser to parse input from given URL
|
1998-05-12 04:59:32 +04:00
|
|
|
* @update gess5/11/98
|
|
|
|
* @param aURL is a descriptor for source document
|
1998-06-01 23:51:52 +04:00
|
|
|
* @param aListener is a listener to forward notifications to
|
1998-05-12 04:59:32 +04:00
|
|
|
* @return TRUE if all went well -- FALSE otherwise
|
|
|
|
*/
|
1999-07-25 21:23:24 +04:00
|
|
|
virtual nsresult Parse(nsIURI* aURL,nsIStreamObserver* aListener,PRBool aEnableVerify=PR_FALSE,void* aKey=0,eParseMode aMode=eParseMode_autodetect);
|
1998-07-14 01:13:09 +04:00
|
|
|
|
1998-07-10 09:35:23 +04:00
|
|
|
/**
|
|
|
|
* Cause parser to parse input from given stream
|
|
|
|
* @update gess5/11/98
|
|
|
|
* @param aStream is the i/o source
|
|
|
|
* @return TRUE if all went well -- FALSE otherwise
|
|
|
|
*/
|
1999-07-25 21:23:24 +04:00
|
|
|
virtual nsresult Parse(nsIInputStream& aStream,PRBool aEnableVerify=PR_FALSE,void* aKey=0,eParseMode aMode=eParseMode_autodetect);
|
1998-07-10 09:35:23 +04:00
|
|
|
|
1998-05-15 02:19:08 +04:00
|
|
|
/**
|
|
|
|
* @update gess5/11/98
|
|
|
|
* @param anHTMLString contains a string-full of real HTML
|
|
|
|
* @param appendTokens tells us whether we should insert tokens inline, or append them.
|
|
|
|
* @return TRUE if all went well -- FALSE otherwise
|
|
|
|
*/
|
1999-07-25 21:23:24 +04:00
|
|
|
virtual nsresult Parse(const nsString& aSourceBuffer,void* aKey,const nsString& aContentType,PRBool aEnableVerify=PR_FALSE,PRBool aLastCall=PR_FALSE,eParseMode aMode=eParseMode_autodetect);
|
1998-05-12 04:59:32 +04:00
|
|
|
|
1999-07-25 21:23:24 +04:00
|
|
|
virtual PRBool IsValidFragment(const nsString& aSourceBuffer,nsITagStack& aStack,PRUint32 anInsertPos,const nsString& aContentType,eParseMode aMode=eParseMode_autodetect);
|
|
|
|
virtual nsresult ParseFragment(const nsString& aSourceBuffer,void* aKey,nsITagStack& aStack,PRUint32 anInsertPos,const nsString& aContentType,eParseMode aMode=eParseMode_autodetect);
|
1999-04-05 10:55:49 +04:00
|
|
|
|
1998-09-02 11:12:49 +04:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Call this when you want control whether or not the parser will parse
|
|
|
|
* and tokenize input (TRUE), or whether it just caches input to be
|
|
|
|
* parsed later (FALSE).
|
|
|
|
*
|
|
|
|
* @update gess 9/1/98
|
|
|
|
* @param aState determines whether we parse/tokenize or just cache.
|
|
|
|
* @return current state
|
|
|
|
*/
|
1999-07-28 03:32:30 +04:00
|
|
|
virtual nsresult EnableParser(PRBool aState);
|
1999-07-08 08:39:38 +04:00
|
|
|
virtual nsresult Terminate(void);
|
1998-09-02 11:12:49 +04:00
|
|
|
|
1999-04-14 02:22:51 +04:00
|
|
|
/**
|
|
|
|
* Call this to query whether the parser is enabled or not.
|
|
|
|
*
|
|
|
|
* @update vidur 4/12/99
|
|
|
|
* @return current state
|
|
|
|
*/
|
|
|
|
virtual PRBool IsParserEnabled();
|
1999-02-01 07:24:37 +03:00
|
|
|
|
|
|
|
/**
|
|
|
|
* This rather arcane method (hack) is used as a signal between the
|
|
|
|
* DTD and the parser. It allows the DTD to tell the parser that content
|
|
|
|
* that comes through (parser::parser(string)) but not consumed should
|
|
|
|
* propagate into the next string based parse call.
|
|
|
|
*
|
|
|
|
* @update gess 9/1/98
|
|
|
|
* @param aState determines whether we propagate unused string content.
|
|
|
|
* @return current state
|
|
|
|
*/
|
|
|
|
void SetUnusedInput(nsString& aBuffer);
|
|
|
|
|
1998-05-12 04:59:32 +04:00
|
|
|
/**
|
|
|
|
* This method gets called (automatically) during incremental parsing
|
|
|
|
* @update gess5/11/98
|
|
|
|
* @return TRUE if all went well, otherwise FALSE
|
|
|
|
*/
|
1999-07-15 12:23:37 +04:00
|
|
|
virtual nsresult ResumeParse(nsIDTD* mDefaultDTD=0, PRBool aIsFinalChunk=PR_FALSE);
|
1998-05-12 04:59:32 +04:00
|
|
|
|
1999-09-02 22:30:31 +04:00
|
|
|
void DebugDumpSource(nsOutputStream& anOutput);
|
1998-05-12 04:59:32 +04:00
|
|
|
|
1998-06-18 03:13:28 +04:00
|
|
|
//*********************************************
|
1998-05-15 02:19:08 +04:00
|
|
|
// These methods are callback methods used by
|
|
|
|
// net lib to let us know about our inputstream.
|
|
|
|
//*********************************************
|
1999-06-21 04:33:51 +04:00
|
|
|
// nsIProgressEventSink methods:
|
1999-07-07 12:08:40 +04:00
|
|
|
NS_IMETHOD OnProgress(nsIChannel* channel, nsISupports* context, PRUint32 Progress, PRUint32 ProgressMax);
|
|
|
|
NS_IMETHOD OnStatus(nsIChannel* channel, nsISupports* context, const PRUnichar* aMmsg);
|
1999-08-22 17:26:18 +04:00
|
|
|
|
1999-06-21 04:33:51 +04:00
|
|
|
// nsIStreamObserver methods:
|
1999-08-22 17:26:18 +04:00
|
|
|
NS_DECL_NSISTREAMOBSERVER
|
|
|
|
|
1999-06-21 04:33:51 +04:00
|
|
|
// nsIStreamListener methods:
|
1999-08-22 17:26:18 +04:00
|
|
|
NS_DECL_NSISTREAMLISTENER
|
|
|
|
|
1999-01-26 04:24:31 +03:00
|
|
|
void PushContext(CParserContext& aContext);
|
|
|
|
CParserContext* PopContext();
|
|
|
|
CParserContext* PeekContext() {return mParserContext;}
|
|
|
|
|
|
|
|
/**
|
|
|
|
*
|
|
|
|
* @update gess 1/22/99
|
|
|
|
* @param
|
|
|
|
* @return
|
|
|
|
*/
|
|
|
|
virtual nsITokenizer* GetTokenizer(void);
|
|
|
|
|
1999-05-05 04:55:54 +04:00
|
|
|
/**
|
|
|
|
* Call this to get a newly constructed tagstack
|
|
|
|
* @update gess 5/05/99
|
|
|
|
* @param aTagStack is an out parm that will contain your result
|
|
|
|
* @return NS_OK if successful, or NS_HTMLPARSER_MEMORY_ERROR on error
|
|
|
|
*/
|
|
|
|
virtual nsresult CreateTagStack(nsITagStack** aTagStack);
|
|
|
|
|
1999-10-01 02:01:48 +04:00
|
|
|
/**
|
|
|
|
* Get the DTD associated with this parser
|
|
|
|
* @update vidur 9/29/99
|
|
|
|
* @param aDTD out param that will contain the result
|
|
|
|
* @return NS_OK if successful, NS_ERROR_FAILURE for runtime error
|
|
|
|
*/
|
|
|
|
NS_IMETHOD GetDTD(nsIDTD** aDTD);
|
|
|
|
|
1999-07-17 01:07:54 +04:00
|
|
|
/**
|
|
|
|
* Call this to access observer dictionary ( internal to parser )
|
|
|
|
* @update harishd 06/27/99
|
|
|
|
* @param
|
|
|
|
* @return
|
|
|
|
*/
|
1999-11-23 06:09:12 +03:00
|
|
|
CObserverService* GetObserverService(void);
|
1999-07-17 01:07:54 +04:00
|
|
|
|
1998-05-12 04:59:32 +04:00
|
|
|
protected:
|
|
|
|
|
|
|
|
/**
|
1998-05-22 00:38:32 +04:00
|
|
|
*
|
|
|
|
* @update gess5/18/98
|
|
|
|
* @param
|
|
|
|
* @return
|
1998-05-12 04:59:32 +04:00
|
|
|
*/
|
1999-01-09 04:09:02 +03:00
|
|
|
nsresult WillBuildModel(nsString& aFilename,nsIDTD* mDefaultDTD=0);
|
1998-05-12 04:59:32 +04:00
|
|
|
|
|
|
|
/**
|
1998-05-22 00:38:32 +04:00
|
|
|
*
|
|
|
|
* @update gess5/18/98
|
|
|
|
* @param
|
|
|
|
* @return
|
1998-05-12 04:59:32 +04:00
|
|
|
*/
|
1999-01-09 04:09:02 +03:00
|
|
|
nsresult DidBuildModel(nsresult anErrorCode);
|
1998-05-12 04:59:32 +04:00
|
|
|
|
|
|
|
/**
|
1998-05-22 00:38:32 +04:00
|
|
|
* This method gets called when the tokens have been consumed, and it's time
|
|
|
|
* to build the model via the content sink.
|
1998-05-12 04:59:32 +04:00
|
|
|
* @update gess5/11/98
|
1998-05-22 00:38:32 +04:00
|
|
|
* @return YES if model building went well -- NO otherwise.
|
1998-05-12 04:59:32 +04:00
|
|
|
*/
|
1999-01-09 04:09:02 +03:00
|
|
|
virtual nsresult BuildModel(void);
|
1998-07-30 03:43:20 +04:00
|
|
|
|
1998-06-18 03:13:28 +04:00
|
|
|
private:
|
1998-05-12 04:59:32 +04:00
|
|
|
|
1998-06-18 03:13:28 +04:00
|
|
|
/*******************************************
|
|
|
|
These are the tokenization methods...
|
|
|
|
*******************************************/
|
1998-05-12 04:59:32 +04:00
|
|
|
|
|
|
|
/**
|
1998-06-18 03:13:28 +04:00
|
|
|
* Part of the code sandwich, this gets called right before
|
|
|
|
* the tokenization process begins. The main reason for
|
|
|
|
* this call is to allow the delegate to do initialization.
|
|
|
|
*
|
|
|
|
* @update gess 3/25/98
|
|
|
|
* @param
|
|
|
|
* @return TRUE if it's ok to proceed
|
1998-05-12 04:59:32 +04:00
|
|
|
*/
|
1999-07-15 12:23:37 +04:00
|
|
|
PRBool WillTokenize(PRBool aIsFinalChunk = PR_FALSE);
|
1998-05-12 04:59:32 +04:00
|
|
|
|
1998-07-14 01:13:09 +04:00
|
|
|
|
1998-05-12 04:59:32 +04:00
|
|
|
/**
|
1998-06-18 03:13:28 +04:00
|
|
|
* This is the primary control routine. It iteratively
|
|
|
|
* consumes tokens until an error occurs or you run out
|
|
|
|
* of data.
|
|
|
|
*
|
|
|
|
* @update gess 3/25/98
|
|
|
|
* @return error code
|
1998-05-12 04:59:32 +04:00
|
|
|
*/
|
1999-07-15 12:23:37 +04:00
|
|
|
nsresult Tokenize(PRBool aIsFinalChunk = PR_FALSE);
|
1998-05-12 04:59:32 +04:00
|
|
|
|
|
|
|
/**
|
1998-06-18 03:13:28 +04:00
|
|
|
* 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
|
1998-05-12 04:59:32 +04:00
|
|
|
*/
|
1999-07-15 12:23:37 +04:00
|
|
|
PRBool DidTokenize(PRBool aIsFinalChunk = PR_FALSE);
|
1998-06-23 04:53:50 +04:00
|
|
|
|
1998-05-15 02:19:08 +04:00
|
|
|
|
|
|
|
protected:
|
1998-05-12 04:59:32 +04:00
|
|
|
//*********************************************
|
|
|
|
// And now, some data members...
|
|
|
|
//*********************************************
|
1998-11-21 10:48:49 +03:00
|
|
|
|
|
|
|
|
1998-07-14 01:13:09 +04:00
|
|
|
CParserContext* mParserContext;
|
1998-07-17 06:35:23 +04:00
|
|
|
PRInt32 mMajorIteration;
|
|
|
|
PRInt32 mMinorIteration;
|
1998-07-14 01:13:09 +04:00
|
|
|
|
|
|
|
nsIStreamObserver* mObserver;
|
1999-06-21 04:33:51 +04:00
|
|
|
nsIProgressEventSink* mProgressEventSink;
|
1998-07-14 01:13:09 +04:00
|
|
|
nsIContentSink* mSink;
|
|
|
|
nsIParserFilter* mParserFilter;
|
1998-07-30 03:43:20 +04:00
|
|
|
PRBool mDTDVerification;
|
1998-11-11 14:55:32 +03:00
|
|
|
nsString mCommand;
|
1998-12-11 20:02:37 +03:00
|
|
|
PRInt32 mStreamStatus;
|
1999-01-26 04:24:31 +03:00
|
|
|
nsITokenObserver* mTokenObserver;
|
1999-02-01 07:24:37 +03:00
|
|
|
nsString mUnusedInput;
|
1999-04-26 21:49:45 +04:00
|
|
|
nsString mCharset;
|
|
|
|
nsCharsetSource mCharsetSource;
|
1999-05-19 09:01:46 +04:00
|
|
|
nsresult mInternalState;
|
1999-09-01 05:01:21 +04:00
|
|
|
CObserverService mObserverService;
|
1999-11-23 06:09:12 +03:00
|
|
|
PRBool mObserversEnabled;
|
1999-09-22 10:19:50 +04:00
|
|
|
|
1999-11-10 06:41:09 +03:00
|
|
|
public:
|
1999-11-12 00:35:34 +03:00
|
|
|
MOZ_TIMER_DECLARE(mParseTime)
|
|
|
|
MOZ_TIMER_DECLARE(mDTDTime)
|
|
|
|
MOZ_TIMER_DECLARE(mTokenizeTime)
|
1998-04-14 00:24:54 +04:00
|
|
|
};
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|