Backing out 8f9ff81ef3fa to try to fix orange.
authorPeter Van der Beken <peterv@propagandism.org>
Tue, 24 Mar 2009 10:43:42 +0100
changeset 26498 14b24e4dbb17f827bfa40a2d48835798fb15adcf
parent 26492 8f9ff81ef3fa875ac4ec7d7edb6ab46aa395e630
child 26499 6cfe70091cfc7906ed5ab624b8cbafccbf34d1fd
push id6106
push userpvanderbeken@mozilla.com
push dateTue, 24 Mar 2009 09:44:40 +0000
treeherdermozilla-central@6cfe70091cfc [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone1.9.2a1pre
Backing out 8f9ff81ef3fa to try to fix orange.
parser/htmlparser/public/nsIDTD.h
parser/htmlparser/public/nsITokenizer.h
parser/htmlparser/src/CNavDTD.cpp
parser/htmlparser/src/CNavDTD.h
parser/htmlparser/src/CParserContext.cpp
parser/htmlparser/src/CParserContext.h
parser/htmlparser/src/nsExpatDriver.cpp
parser/htmlparser/src/nsExpatDriver.h
parser/htmlparser/src/nsHTMLTokenizer.cpp
parser/htmlparser/src/nsHTMLTokenizer.h
parser/htmlparser/src/nsParser.cpp
parser/htmlparser/src/nsViewSourceHTML.cpp
--- a/parser/htmlparser/public/nsIDTD.h
+++ b/parser/htmlparser/public/nsIDTD.h
@@ -98,25 +98,28 @@ public:
 
     /**
      * Called by the parser after the parsing process has concluded
      * @update  gess5/18/98
      * @param   anErrorCode - contains error code resulting from parse process
      * @return
      */
     NS_IMETHOD DidBuildModel(nsresult anErrorCode, PRBool aNotifySink,
-                             nsIParser* aParser) = 0;
+                             nsIParser* aParser,
+                             nsIContentSink* aSink) = 0;
 
     /**
      * Called by the parser after the parsing process has concluded
      * @update  gess5/18/98
      * @param   anErrorCode - contains error code resulting from parse process
      * @return
      */
-    NS_IMETHOD BuildModel(nsIParser* aParser, nsITokenizer* aTokenizer) = 0;
+    NS_IMETHOD BuildModel(nsIParser* aParser, nsITokenizer* aTokenizer,
+                          nsITokenObserver* anObserver,
+                          nsIContentSink* aSink) = 0;
 
     /**
      * Called during model building phase of parse process. Each token
      * created during the parse phase is stored in a deque (in the
      * parser) and are passed to this method so that the DTD can
      * process the token. Ultimately, the DTD will transform given
      * token into calls onto a contentsink.
      * @update  gess 3/25/98
@@ -126,25 +129,25 @@ public:
     NS_IMETHOD HandleToken(CToken* aToken,nsIParser* aParser) = 0;
 
     /**
      * If the parse process gets interrupted midway, this method is
      * called by the parser prior to resuming the process.
      * @update  gess5/18/98
      * @return ignored
      */
-    NS_IMETHOD WillResumeParse() = 0;
+    NS_IMETHOD WillResumeParse(nsIContentSink* aSink) = 0;
 
     /**
      * If the parse process gets interrupted, this method is called by
      * the parser to notify the DTD that interruption will occur.
      * @update  gess5/18/98
      * @return ignored
      */
-    NS_IMETHOD WillInterruptParse() = 0;
+    NS_IMETHOD WillInterruptParse(nsIContentSink* aSink) = 0;
 
     /**
      * This method is called to determine whether or not a tag of one
      * type can contain a tag of another type.
      *
      * @update  gess 3/25/98
      * @param   aParent -- int tag of parent container
      * @param   aChild -- int tag of child container
@@ -170,27 +173,24 @@ public:
      *
      * @update  harishd 07/22/99
      * @param
      * @return
      */
     NS_IMETHOD_(void) Terminate() = 0;
 
     NS_IMETHOD_(PRInt32) GetType() = 0;
-
-    NS_IMETHOD_(nsITokenizer*) CreateTokenizer() = 0;
 };
 
 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, PRBool aNotifySink, nsIParser* aParser);\
-    NS_IMETHOD BuildModel(nsIParser* aParser, nsITokenizer* aTokenizer);\
-    NS_IMETHOD HandleToken(CToken* aToken, nsIParser* aParser);\
-    NS_IMETHOD WillResumeParse();\
-    NS_IMETHOD WillInterruptParse();\
+    NS_IMETHOD DidBuildModel(nsresult anErrorCode,PRBool aNotifySink,nsIParser* aParser,nsIContentSink* aSink);\
+    NS_IMETHOD BuildModel(nsIParser* aParser,nsITokenizer* aTokenizer,nsITokenObserver* anObserver,nsIContentSink* aSink);\
+    NS_IMETHOD HandleToken(CToken* aToken,nsIParser* aParser);\
+    NS_IMETHOD WillResumeParse(nsIContentSink* aSink = 0);\
+    NS_IMETHOD WillInterruptParse(nsIContentSink* aSink = 0);\
     NS_IMETHOD_(PRBool) CanContain(PRInt32 aParent,PRInt32 aChild) const;\
     NS_IMETHOD_(PRBool) IsContainer(PRInt32 aTag) const;\
     NS_IMETHOD_(void)  Terminate();\
-    NS_IMETHOD_(PRInt32) GetType();\
-    NS_IMETHOD_(nsITokenizer*) CreateTokenizer();
+    NS_IMETHOD_(PRInt32) GetType();
 #endif /* nsIDTD_h___ */
--- a/parser/htmlparser/public/nsITokenizer.h
+++ b/parser/htmlparser/public/nsITokenizer.h
@@ -51,16 +51,24 @@
 class CToken;
 class nsScanner;
 class nsDeque;
 class nsTokenAllocator;
 
 #define NS_ITOKENIZER_IID      \
   {0xe4238ddc, 0x9eb6,  0x11d2, {0xba, 0xa5, 0x0,     0x10, 0x4b, 0x98, 0x3f, 0xd4 }}
 
+/**
+ * This interface is used as a callback to objects interested
+ * in observing the token stream created from the parse process.
+ */
+class nsITokenObserver {
+public:
+  virtual PRBool  operator()(CToken* aToken)=0;
+};
 
 /***************************************************************
   Notes: 
  ***************************************************************/
 
 
 class nsITokenizer : public nsISupports {
 public:
--- a/parser/htmlparser/src/CNavDTD.cpp
+++ b/parser/htmlparser/src/CNavDTD.cpp
@@ -248,17 +248,19 @@ CNavDTD::WillBuildModel(const CParserCon
     }
   }
 
   return result;
 }
 
 nsresult
 CNavDTD::BuildModel(nsIParser* aParser,
-                    nsITokenizer* aTokenizer)
+                    nsITokenizer* aTokenizer,
+                    nsITokenObserver* anObserver,
+                    nsIContentSink* aSink)
 {
   NS_PRECONDITION(mBodyContext != nsnull,
                   "Create a context before calling build model");
 
   nsresult result = NS_OK;
 
   if (!aTokenizer || !aParser) {
     return NS_OK;
@@ -356,49 +358,51 @@ CNavDTD::BuildModel(nsIParser* aParser,
 
   mTokenizer = oldTokenizer;
   return result;
 }
 
 nsresult
 CNavDTD::BuildNeglectedTarget(eHTMLTags aTarget,
                               eHTMLTokenTypes aType,
-                              nsIParser* aParser)
+                              nsIParser* aParser,
+                              nsIContentSink* aSink)
 { 
   NS_ASSERTION(mTokenizer, "tokenizer is null! unable to build target.");
   NS_ASSERTION(mTokenAllocator, "unable to create tokens without an allocator.");
   if (!mTokenizer || !mTokenAllocator) {
     return NS_OK;
   }
 
   CToken* target = mTokenAllocator->CreateTokenOfType(aType, aTarget);
   NS_ENSURE_TRUE(target, NS_ERROR_OUT_OF_MEMORY);
   mTokenizer->PushTokenFront(target);
-  return BuildModel(aParser, mTokenizer);
+  return BuildModel(aParser, mTokenizer, 0, aSink);
 }
 
 nsresult
 CNavDTD::DidBuildModel(nsresult anErrorCode,
                        PRBool aNotifySink,
-                       nsIParser* aParser)
+                       nsIParser* aParser,
+                       nsIContentSink* aSink)
 {
-  if (!mSink) {
+  if (!aSink) {
     return NS_OK;
   }
 
   nsresult result = NS_OK;
   if (aParser && aNotifySink) {
     if (NS_OK == anErrorCode) {
       if (!(mFlags & NS_DTD_FLAG_HAS_MAIN_CONTAINER)) {
         // This document is not a frameset document, however, it did not contain
         // a body tag either. So, make one!. Note: Body tag is optional per spec..
         // Also note: We ignore the return value of BuildNeglectedTarget, we
         // can't reasonably respond to errors (or requests to block) at this
         // point in the parsing process.
-        BuildNeglectedTarget(eHTMLTag_body, eToken_start, aParser);
+        BuildNeglectedTarget(eHTMLTag_body, eToken_start, aParser, aSink);
       }
       if (mFlags & NS_DTD_FLAG_MISPLACED_CONTENT) {
         // Looks like the misplaced contents are not processed yet.
         // Here is our last chance to handle the misplaced content.
 
         // Keep track of the top index.
         PRInt32 topIndex = mBodyContext->mContextTopIndex;
         
@@ -426,17 +430,17 @@ CNavDTD::DidBuildModel(nsresult anErrorC
 
       // Now let's disable style handling to save time when closing remaining
       // stack members.
       mFlags &= ~NS_DTD_FLAG_ENABLE_RESIDUAL_STYLE;
       while (mBodyContext->GetCount() > 0) { 
         result = CloseContainersTo(mBodyContext->Last(), PR_FALSE);
         if (NS_FAILED(result)) {
           //No matter what, you need to call did build model.
-          mSink->DidBuildModel();
+          aSink->DidBuildModel();
           return result;
         }
       } 
     } else {
       // If you're here, then an error occured, but we still have nodes on the stack.
       // At a minimum, we should grab the nodes and recycle them.
       // Just to be correct, we'll also recycle the nodes.
       while (mBodyContext->GetCount() > 0) { 
@@ -451,38 +455,32 @@ CNavDTD::DidBuildModel(nsresult anErrorC
     // by forcefully recycling any tokens we might find there.
     CToken* theToken = 0;
     while ((theToken = (CToken*)mMisplacedContent.Pop())) {
       IF_FREE(theToken, mTokenAllocator);
     }
   }
 
   // No matter what, you need to call did build model.
-  return mSink->DidBuildModel(); 
+  return aSink->DidBuildModel(); 
 }
 
 NS_IMETHODIMP_(void) 
 CNavDTD::Terminate() 
 { 
   mFlags |= NS_DTD_FLAG_STOP_PARSING; 
 }
 
 
 NS_IMETHODIMP_(PRInt32) 
 CNavDTD::GetType() 
 { 
   return NS_IPARSER_FLAG_HTML; 
 }
 
-NS_IMETHODIMP_(nsITokenizer*)
-CNavDTD::CreateTokenizer()
-{
-  return new nsHTMLTokenizer(mDTDMode, mDocType, mParserCommand, mSink);
-}
-
 /**
  * Text and some tags require a body when they're added, this function returns
  * true for those tags.
  *
  * @param aToken The current token that we care about.
  * @param aTokenizer A tokenizer that we can get the tags attributes off of.
  * @return PR_TRUE if aToken does indeed force the body to open.
  */
@@ -3149,35 +3147,35 @@ CNavDTD::CreateContextStackFor(eHTMLTags
     // Note: These tokens should all wind up on contextstack, so don't recycle
     // them.
     CToken *theToken = mTokenAllocator->CreateTokenOfType(eToken_start, theTag);
     HandleToken(theToken, mParser);
   }
 }
 
 nsresult
-CNavDTD::WillResumeParse()
+CNavDTD::WillResumeParse(nsIContentSink* aSink)
 {
   STOP_TIMER();
   MOZ_TIMER_DEBUGLOG(("Stop: Parse Time: CNavDTD::WillResumeParse(), this=%p\n", this));
 
-  nsresult result = mSink ? mSink->WillResume() : NS_OK;
+  nsresult result = aSink ? aSink->WillResume() : NS_OK;
 
   MOZ_TIMER_DEBUGLOG(("Start: Parse Time: CNavDTD::WillResumeParse(), this=%p\n", this));
   START_TIMER();
 
   return result;
 }
 
 nsresult
-CNavDTD::WillInterruptParse()
+CNavDTD::WillInterruptParse(nsIContentSink* aSink)
 {
   STOP_TIMER();
   MOZ_TIMER_DEBUGLOG(("Stop: Parse Time: CNavDTD::WillInterruptParse(), this=%p\n", this));
 
-  nsresult result = mSink ? mSink->WillInterrupt() : NS_OK;
+  nsresult result = aSink ? aSink->WillInterrupt() : NS_OK;
 
   MOZ_TIMER_DEBUGLOG(("Start: Parse Time: CNavDTD::WillInterruptParse(), this=%p\n", this));
   START_TIMER();
 
   return result;
 }
 
--- a/parser/htmlparser/src/CNavDTD.h
+++ b/parser/htmlparser/src/CNavDTD.h
@@ -291,17 +291,17 @@ private:
                                         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,
-                                     nsIParser* aParser);
+                                     nsIParser* aParser, nsIContentSink* aSink);
 
     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.
--- a/parser/htmlparser/src/CParserContext.cpp
+++ b/parser/htmlparser/src/CParserContext.cpp
@@ -90,16 +90,56 @@ CParserContext::SetMimeType(const nsACSt
            mMimeType.EqualsLiteral(kSVGTextContentType)          ||
 #endif
            mMimeType.EqualsLiteral(kRDFApplicationContentType)   ||
            mMimeType.EqualsLiteral(kRDFTextContentType))
     mDocType = eXML;
 }
 
 nsresult
-CParserContext::GetTokenizer(nsIDTD* aDTD, nsITokenizer*& aTokenizer)
+CParserContext::GetTokenizer(nsIDTD* aDTD,
+                             nsIContentSink* aSink,
+                             nsITokenizer*& aTokenizer)
 {
-  if (!mTokenizer)
-    mTokenizer = aDTD->CreateTokenizer();
-  return (aTokenizer = mTokenizer)
-    ? NS_OK
-    : NS_ERROR_OUT_OF_MEMORY;
+  nsresult result = NS_OK;
+  PRInt32 type = aDTD ? aDTD->GetType() : NS_IPARSER_FLAG_HTML;
+
+  if (!mTokenizer) {
+    if (type == NS_IPARSER_FLAG_HTML || mParserCommand == eViewSource) {
+      nsCOMPtr<nsIHTMLContentSink> theSink = do_QueryInterface(aSink);
+      PRUint16 theFlags = 0;
+
+      if (theSink) {
+        // XXX This code is repeated both here and in CNavDTD. Can the two
+        // callsites be combined?
+        PRBool enabled;
+        theSink->IsEnabled(eHTMLTag_frameset, &enabled);
+        if(enabled) {
+          theFlags |= NS_IPARSER_FLAG_FRAMES_ENABLED;
+        }
+        
+        theSink->IsEnabled(eHTMLTag_script, &enabled);
+        if(enabled) {
+          theFlags |= NS_IPARSER_FLAG_SCRIPT_ENABLED;
+        }
+      }
+
+      mTokenizer = new nsHTMLTokenizer(mDTDMode, mDocType,
+                                       mParserCommand, theFlags);
+      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);
+    }
+  }
+
+  aTokenizer = mTokenizer;
+
+  return result;
 }
--- a/parser/htmlparser/src/CParserContext.h
+++ b/parser/htmlparser/src/CParserContext.h
@@ -68,17 +68,19 @@ public:
                   void* aKey = 0,
                   eParserCommands aCommand = eViewNormal,
                   nsIRequestObserver* aListener = 0,
                   eAutoDetectResult aStatus = eUnknownDetect,
                   PRBool aCopyUnused = PR_FALSE);
 
     ~CParserContext();
 
-    nsresult GetTokenizer(nsIDTD* aDTD, nsITokenizer*& aTokenizer);
+    nsresult GetTokenizer(nsIDTD* aDTD,
+                          nsIContentSink* aSink,
+                          nsITokenizer*& aTokenizer);
     void  SetMimeType(const nsACString& aMimeType);
 
     nsCOMPtr<nsIRequest> mRequest; // provided by necko to differnciate different input streams
                                    // why is mRequest strongly referenced? see bug 102376.
     nsCOMPtr<nsIRequestObserver> mListener;
     void* const          mKey;
     nsCOMPtr<nsITokenizer> mTokenizer;
     CParserContext* const mPrevContext;
--- a/parser/htmlparser/src/nsExpatDriver.cpp
+++ b/parser/htmlparser/src/nsExpatDriver.cpp
@@ -798,22 +798,20 @@ nsExpatDriver::OpenInputStreamFromExtern
     nsCOMPtr<nsIURI> localURI;
     if (!IsLoadableDTD(mCatalogData, uri, getter_AddRefs(localURI))) {
       return NS_ERROR_NOT_IMPLEMENTED;
     }
 
     localURI.swap(uri);
   }
 
+  nsCOMPtr<nsIContentSink> sink = do_QueryInterface(mSink);
   nsCOMPtr<nsIDocument> doc;
-  NS_ASSERTION(mSink == nsCOMPtr<nsIExpatSink>(do_QueryInterface(mOriginalSink)),
-               "In nsExpatDriver::OpenInputStreamFromExternalDTD: "
-               "mOriginalSink not the same object as mSink?");
-  if (mOriginalSink)
-    doc = do_QueryInterface(mOriginalSink->GetTarget());
+  if (sink)
+    doc = do_QueryInterface(sink->GetTarget());
   PRInt16 shouldLoad = nsIContentPolicy::ACCEPT;
   rv = NS_CheckContentLoadPolicy(nsIContentPolicy::TYPE_DTD,
                                 uri,
                                 (doc ? doc->NodePrincipal() : nsnull),
                                 doc,
                                 EmptyCString(), //mime guess
                                 nsnull,         //extra
                                 &shouldLoad);
@@ -1229,18 +1227,16 @@ nsExpatDriver::WillBuildModel(const CPar
   mSink = do_QueryInterface(aSink);
   if (!mSink) {
     NS_ERROR("nsExpatDriver didn't get an nsIExpatSink");
     // Make sure future calls to us bail out as needed
     mInternalState = NS_ERROR_UNEXPECTED;
     return mInternalState;
   }
 
-  mOriginalSink = aSink;
-
   static const XML_Memory_Handling_Suite memsuite =
     {
       (void *(*)(size_t))PR_Malloc,
       (void *(*)(void *, size_t))PR_Realloc,
       PR_Free
     };
 
   static const PRUnichar kExpatSeparator[] = { kExpatSeparatorChar, '\0' };
@@ -1298,64 +1294,60 @@ nsExpatDriver::WillBuildModel(const CPar
   // XML must detect invalid character convertion
   aParserContext.mScanner->OverrideReplacementCharacter(0xffff);
 
   return aSink->WillBuildModel();
 }
 
 NS_IMETHODIMP
 nsExpatDriver::BuildModel(nsIParser* aParser,
-                          nsITokenizer* aTokenizer)
+                          nsITokenizer* aTokenizer,
+                          nsITokenObserver* anObserver,
+                          nsIContentSink* aSink)
 {
   return mInternalState;
 }
 
 NS_IMETHODIMP
 nsExpatDriver::DidBuildModel(nsresult anErrorCode,
                              PRBool aNotifySink,
-                             nsIParser* aParser)
+                             nsIParser* aParser,
+                             nsIContentSink* aSink)
 {
-  NS_ASSERTION(mSink == nsCOMPtr<nsIExpatSink>(do_QueryInterface(mOriginalSink)),
-               "In nsExpatDriver::DidBuildModel: mOriginalSink not the same object as mSink?");
-  // Check for mOriginalSink is intentional. This would make sure
+  // Check for mSink is intentional. This would make sure
   // that DidBuildModel() is called only once on the sink.
   nsresult result = NS_OK;
-  if (mOriginalSink) {
-    result = mOriginalSink->DidBuildModel();
-    mOriginalSink = nsnull;
+  if (mSink) {
+    result = aSink->DidBuildModel();
+    mSink = nsnull;
   }
 
-  mSink = nsnull;
   mExtendedSink = nsnull;
 
   return result;
 }
 
 NS_IMETHODIMP
 nsExpatDriver::WillTokenize(PRBool aIsFinalChunk,
                             nsTokenAllocator* aTokenAllocator)
 {
   mIsFinalChunk = aIsFinalChunk;
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsExpatDriver::WillResumeParse()
+nsExpatDriver::WillResumeParse(nsIContentSink* aSink)
 {
-  NS_ASSERTION(mSink == nsCOMPtr<nsIExpatSink>(do_QueryInterface(mOriginalSink)),
-               "In nsExpatDriver::WillResumeParse: mOriginalSink not the same object as mSink?");
-  return mOriginalSink ? mOriginalSink->WillResume() : NS_OK;
+  return aSink ? aSink->WillResume() : NS_OK;
 }
 
 NS_IMETHODIMP
-nsExpatDriver::WillInterruptParse()
+nsExpatDriver::WillInterruptParse(nsIContentSink* aSink)
 {
-  NS_ASSERTION(mSink == nsCOMPtr<nsIExpatSink>(do_QueryInterface(mOriginalSink)),
-               "In nsExpatDriver::WillInterruptParse: mOriginalSink not the same object as mSink?");
-  return mOriginalSink ? mOriginalSink->WillInterrupt() : NS_OK;
+  return aSink ? aSink->WillInterrupt() : NS_OK;
 }
 
 NS_IMETHODIMP
 nsExpatDriver::DidTokenize(PRBool aIsFinalChunk)
 {
   return NS_OK;
 }
 
@@ -1370,22 +1362,16 @@ nsExpatDriver::Terminate()
 }
 
 NS_IMETHODIMP_(PRInt32)
 nsExpatDriver::GetType()
 {
   return NS_IPARSER_FLAG_XML;
 }
 
-NS_IMETHODIMP_(nsITokenizer*)
-nsExpatDriver::CreateTokenizer()
-{
-  return static_cast<nsITokenizer*>(this);
-}
-
 /*************************** Unused methods **********************************/
 
 NS_IMETHODIMP_(CToken*)
 nsExpatDriver::PushTokenFront(CToken* aToken)
 {
   return 0;
 }
 
--- a/parser/htmlparser/src/nsExpatDriver.h
+++ b/parser/htmlparser/src/nsExpatDriver.h
@@ -36,17 +36,16 @@
  * ***** END LICENSE BLOCK ***** */
 
 #ifndef NS_EXPAT_DRIVER__
 #define NS_EXPAT_DRIVER__
 
 #include "expat_config.h"
 #include "expat.h"
 #include "nsCOMPtr.h"
-#include "nsAutoPtr.h"
 #include "nsString.h"
 #include "nsIDTD.h"
 #include "nsITokenizer.h"
 #include "nsIInputStream.h"
 #include "nsIParser.h"
 #include "nsCycleCollectionParticipant.h"
 
 class nsIExpatSink;
@@ -152,20 +151,15 @@ private:
   // Necko
   PRPackedBool     mIsFinalChunk;
 
   nsresult         mInternalState;
 
   // The length of the data in Expat's buffer (in number of PRUnichars).
   PRUint32         mExpatBuffered;
 
-  // These sinks all refer the same conceptual object. mOriginalSink is
-  // identical with the nsIContentSink* passed to WillBuildModel, and exists
-  // only to avoid QI-ing back to nsIContentSink*.
-  nsCOMPtr<nsIContentSink> mOriginalSink;
   nsCOMPtr<nsIExpatSink> mSink;
   nsCOMPtr<nsIExtendedExpatSink> mExtendedSink;
-
   const nsCatalogData* mCatalogData; // weak
   nsString         mURISpec;
 };
 
 #endif
--- a/parser/htmlparser/src/nsHTMLTokenizer.cpp
+++ b/parser/htmlparser/src/nsHTMLTokenizer.cpp
@@ -68,29 +68,19 @@ NS_IMPL_ISUPPORTS1(nsHTMLTokenizer, nsIT
  * 
  * @param  aParseMode The current mode the document is in (quirks, etc.)
  * @param  aDocType The document type of the current document
  * @param  aCommand What we are trying to do (view-source, parse a fragment, etc.)
  */
 nsHTMLTokenizer::nsHTMLTokenizer(PRInt32 aParseMode,
                                  eParserDocType aDocType,
                                  eParserCommands aCommand,
-                                 nsIHTMLContentSink* aSink)
-  : nsITokenizer(), mTokenDeque(0), mFlags(0)
+                                 PRUint16 aFlags) :
+  nsITokenizer(), mTokenDeque(0), mFlags(aFlags)
 {
-  if (aSink) {
-    PRBool enabled;
-    aSink->IsEnabled(eHTMLTag_frameset, &enabled);
-    if (enabled)
-      mFlags |= NS_IPARSER_FLAG_FRAMES_ENABLED;
-    aSink->IsEnabled(eHTMLTag_script, &enabled);
-    if (enabled)
-      mFlags |= NS_IPARSER_FLAG_SCRIPT_ENABLED;
-  }
-
   if (aParseMode == eDTDMode_full_standards ||
       aParseMode == eDTDMode_almost_standards) {
     mFlags |= NS_IPARSER_FLAG_STRICT_MODE;
   } else if (aParseMode == eDTDMode_quirks)  {
     mFlags |= NS_IPARSER_FLAG_QUIRKS_MODE;
   } else if (aParseMode == eDTDMode_autodetect) {
     mFlags |= NS_IPARSER_FLAG_AUTO_DETECT_MODE;
   } else {
--- a/parser/htmlparser/src/nsHTMLTokenizer.h
+++ b/parser/htmlparser/src/nsHTMLTokenizer.h
@@ -65,17 +65,17 @@
 class nsHTMLTokenizer : public nsITokenizer {
 public:
   
   NS_DECL_ISUPPORTS
   NS_DECL_NSITOKENIZER
   nsHTMLTokenizer(PRInt32 aParseMode = eDTDMode_quirks,
                   eParserDocType aDocType = eHTML_Quirks,
                   eParserCommands aCommand = eViewNormal,
-                  nsIHTMLContentSink* aSink = 0);
+                  PRUint16 aFlags = 0);
   virtual ~nsHTMLTokenizer();
 
 protected:
 
   nsresult ConsumeTag(PRUnichar aChar,CToken*& aToken,nsScanner& aScanner,PRBool& aFlushTokens);
   nsresult ConsumeStartTag(PRUnichar aChar,CToken*& aToken,nsScanner& aScanner,PRBool& aFlushTokens);
   nsresult ConsumeEndTag(PRUnichar aChar,CToken*& aToken,nsScanner& aScanner);
   nsresult ConsumeAttributes(PRUnichar aChar, CToken* aToken, nsScanner& aScanner);
--- a/parser/htmlparser/src/nsParser.cpp
+++ b/parser/htmlparser/src/nsParser.cpp
@@ -1503,17 +1503,17 @@ nsParser::WillBuildModel(nsString& aFile
   }
 
   NS_ASSERTION(!mDTD || !mParserContext->mPrevContext,
                "Clobbering DTD for non-root parser context!");
   mDTD = FindSuitableDTD(*mParserContext);
   NS_ENSURE_TRUE(mDTD, NS_ERROR_OUT_OF_MEMORY);
 
   nsITokenizer* tokenizer;
-  nsresult rv = mParserContext->GetTokenizer(mDTD, tokenizer);
+  nsresult rv = mParserContext->GetTokenizer(mDTD, mSink, tokenizer);
   NS_ENSURE_SUCCESS(rv, rv);
 
   return mDTD->WillBuildModel(*mParserContext, tokenizer, mSink);
 }
 
 /**
  * This gets called when the parser is done with its input.
  * Note that the parser may have been called recursively, so we
@@ -1526,17 +1526,17 @@ nsParser::DidBuildModel(nsresult anError
 
   if (IsComplete()) {
     if (mParserContext && !mParserContext->mPrevContext) {
       // Let sink know if we're about to end load because we've been terminated.
       // In that case we don't want it to run deferred scripts.
       PRBool terminated = mInternalState == NS_ERROR_HTMLPARSER_STOPPARSING;
       if (mDTD && mSink &&
           mSink->ReadyToCallDidBuildModel(terminated)) {
-        result = mDTD->DidBuildModel(anErrorCode,PR_TRUE,this);
+        result = mDTD->DidBuildModel(anErrorCode,PR_TRUE,this,mSink);
       }
 
       //Ref. to bug 61462.
       mParserContext->mRequest = 0;
     }
   }
 
   return result;
@@ -2222,17 +2222,17 @@ nsParser::ResumeParse(PRBool allowIterat
 
     result = WillBuildModel(mParserContext->mScanner->GetFilename());
     if (NS_FAILED(result)) {
       mFlags &= ~NS_PARSER_FLAG_CAN_TOKENIZE;
       return result;
     }
 
     if (mDTD) {
-      mDTD->WillResumeParse();
+      mDTD->WillResumeParse(mSink);
       PRBool theIterationIsOk = PR_TRUE;
 
       while (result == NS_OK && theIterationIsOk) {
         if (!mUnusedInput.IsEmpty() && mParserContext->mScanner) {
           // -- Ref: Bug# 22485 --
           // Insert the unused input into the source buffer
           // as if it was read from the input stream.
           // Adding UngetReadable() per vidur!!
@@ -2260,17 +2260,17 @@ nsParser::ResumeParse(PRBool allowIterat
         // down the parser, it's important to check whether the input buffer
         // has been scanned to completion (theTokenizerResult should be kEOF).
         // kEOF -> End of buffer.
 
         // If we're told to block the parser, we disable all further parsing
         // (and cache any data coming in) until the parser is re-enabled.
         if (NS_ERROR_HTMLPARSER_BLOCK == result) {
           if (mDTD) {
-            mDTD->WillInterruptParse();
+            mDTD->WillInterruptParse(mSink);
           }
 
           if (mFlags & NS_PARSER_FLAG_PARSER_ENABLED) {
             // If we were blocked by a recursive invocation, don't re-block.
             BlockParser();
             SpeculativelyParse();
           }
           return NS_OK;
@@ -2327,17 +2327,17 @@ nsParser::ResumeParse(PRBool allowIterat
             }
           }
         }
 
         if (theTokenizerResult == kEOF ||
             result == NS_ERROR_HTMLPARSER_INTERRUPTED) {
           result = (result == NS_ERROR_HTMLPARSER_INTERRUPTED) ? NS_OK : result;
           if (mDTD) {
-            mDTD->WillInterruptParse();
+            mDTD->WillInterruptParse(mSink);
           }
         }
       }
     } else {
       mInternalState = result = NS_ERROR_HTMLPARSER_UNRESOLVEDDTD;
     }
   }
 
@@ -2353,23 +2353,23 @@ nsParser::ResumeParse(PRBool allowIterat
  */
 nsresult
 nsParser::BuildModel()
 {
   nsITokenizer* theTokenizer = nsnull;
 
   nsresult result = NS_OK;
   if (mParserContext) {
-    result = mParserContext->GetTokenizer(mDTD, theTokenizer);
+    result = mParserContext->GetTokenizer(mDTD, mSink, theTokenizer);
   }
 
   if (NS_SUCCEEDED(result)) {
     if (mDTD) {
       MOZ_TIMER_START(mDTDTime);
-      result = mDTD->BuildModel(this, theTokenizer);
+      result = mDTD->BuildModel(this, theTokenizer, nsnull, mSink);
       MOZ_TIMER_STOP(mDTDTime);
     }
   } else {
     mInternalState = result = NS_ERROR_HTMLPARSER_BADTOKENIZER;
   }
   return result;
 }
 
@@ -2976,17 +2976,17 @@ nsParser::OnStopRequest(nsIRequest *requ
 PRBool
 nsParser::WillTokenize(PRBool aIsFinalChunk)
 {
   if (!mParserContext) {
     return PR_TRUE;
   }
 
   nsITokenizer* theTokenizer;
-  nsresult result = mParserContext->GetTokenizer(mDTD, theTokenizer);
+  nsresult result = mParserContext->GetTokenizer(mDTD, mSink, theTokenizer);
   NS_ENSURE_SUCCESS(result, PR_FALSE);
   return NS_SUCCEEDED(theTokenizer->WillTokenize(aIsFinalChunk,
                                                  &mTokenAllocator));
 }
 
 
 /**
  * This is the primary control routine to consume tokens.
@@ -2994,17 +2994,17 @@ nsParser::WillTokenize(PRBool aIsFinalCh
  * you run out of data.
  */
 nsresult nsParser::Tokenize(PRBool aIsFinalChunk)
 {
   nsITokenizer* theTokenizer;
 
   nsresult result = NS_ERROR_NOT_AVAILABLE;
   if (mParserContext) {
-    result = mParserContext->GetTokenizer(mDTD, theTokenizer);
+    result = mParserContext->GetTokenizer(mDTD, mSink, theTokenizer);
   }
 
   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) {
@@ -3069,17 +3069,17 @@ nsresult nsParser::Tokenize(PRBool aIsFi
 PRBool
 nsParser::DidTokenize(PRBool aIsFinalChunk)
 {
   if (!mParserContext) {
     return PR_TRUE;
   }
 
   nsITokenizer* theTokenizer;
-  nsresult rv = mParserContext->GetTokenizer(mDTD, theTokenizer);
+  nsresult rv = mParserContext->GetTokenizer(mDTD, mSink, theTokenizer);
   NS_ENSURE_SUCCESS(rv, PR_FALSE);
 
   rv = theTokenizer->DidTokenize(aIsFinalChunk);
   return NS_SUCCEEDED(rv);
 }
 
 /**
  * Get the channel associated with this parser
--- a/parser/htmlparser/src/nsViewSourceHTML.cpp
+++ b/parser/htmlparser/src/nsViewSourceHTML.cpp
@@ -333,19 +333,17 @@ nsresult CViewSourceHTML::WillBuildModel
 /**
   * The parser uses a code sandwich to wrap the parsing process. Before
   * the process begins, WillBuildModel() is called. Afterwards the parser
   * calls DidBuildModel().
   * @update gess5/18/98
   * @param  aFilename is the name of the file being parsed.
   * @return error code (almost always 0)
   */
-NS_IMETHODIMP CViewSourceHTML::BuildModel(nsIParser* aParser,
-                                          nsITokenizer* aTokenizer)
-{
+NS_IMETHODIMP CViewSourceHTML::BuildModel(nsIParser* aParser,nsITokenizer* aTokenizer,nsITokenObserver* anObserver,nsIContentSink* aSink) {
   nsresult result=NS_OK;
 
   if(aTokenizer && aParser) {
 
     nsITokenizer*  oldTokenizer=mTokenizer;
     mTokenizer=aTokenizer;
     nsTokenAllocator* theAllocator=mTokenizer->GetTokenAllocator();
 
@@ -544,20 +542,17 @@ void CViewSourceHTML::AddAttrToNode(nsCP
 }
 
 /**
  *
  * @update  gess5/18/98
  * @param
  * @return
  */
-NS_IMETHODIMP CViewSourceHTML::DidBuildModel(nsresult anErrorCode,
-                                             PRBool aNotifySink,
-                                             nsIParser* aParser)
-{
+NS_IMETHODIMP CViewSourceHTML::DidBuildModel(nsresult anErrorCode,PRBool aNotifySink,nsIParser* aParser,nsIContentSink* aSink){
   nsresult result= NS_OK;
 
   //ADD CODE HERE TO CLOSE OPEN CONTAINERS...
 
   if(aParser){
 
     mParser=(nsParser*)aParser;  //debug XXX
     STOP_TIMER();
@@ -611,45 +606,37 @@ NS_IMETHODIMP_(void)
 CViewSourceHTML::Terminate() {
 }
 
 NS_IMETHODIMP_(PRInt32)
 CViewSourceHTML::GetType() {
   return NS_IPARSER_FLAG_HTML;
 }
 
-NS_IMETHODIMP_(nsITokenizer*)
-CViewSourceHTML::CreateTokenizer()
-{
-  return new nsHTMLTokenizer(mDTDMode, mDocType, mParserCommand, mSink);
-}
-
 /**
  *
  * @update  gess5/18/98
  * @param
  * @return
  */
-NS_IMETHODIMP CViewSourceHTML::WillResumeParse()
-{
+NS_IMETHODIMP CViewSourceHTML::WillResumeParse(nsIContentSink* aSink){
   nsresult result = NS_OK;
   if(mSink) {
     result = mSink->WillResume();
   }
   return result;
 }
 
 /**
  *
  * @update  gess5/18/98
  * @param
  * @return
  */
-NS_IMETHODIMP CViewSourceHTML::WillInterruptParse()
-{
+NS_IMETHODIMP CViewSourceHTML::WillInterruptParse(nsIContentSink* aSink){
   nsresult result = NS_OK;
   if(mSink) {
     result = mSink->WillInterrupt();
   }
   return result;
 }
 
 /**