Backed out changeset 4c4d0bf8622e for failing unit tests.
authorBen Turner <bent.mozilla@gmail.com>
Wed, 14 Jan 2009 18:22:41 -0800
changeset 23694 ea386d2dfc1c6ce65b6d668605ecddae22bb2fc0
parent 23693 4c4d0bf8622e9c0e17857e27ea8724d98f601cb6
child 23696 69765da46ccf0aa01a4ec1969d7dd1c1e054aff5
push id1
push userroot
push dateTue, 26 Apr 2011 22:38:44 +0000
treeherdermozilla-beta@bfdb6e623a36 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone1.9.2a1pre
backs out4c4d0bf8622e9c0e17857e27ea8724d98f601cb6
Backed out changeset 4c4d0bf8622e for failing unit tests.
content/base/public/nsIDocument.h
content/base/src/nsContentSink.cpp
content/base/src/nsContentSink.h
content/base/src/nsDocument.cpp
content/base/src/nsDocument.h
content/base/src/nsScriptLoader.h
content/base/test/Makefile.in
content/base/test/test_bug461555.html
content/html/document/src/nsHTMLContentSink.cpp
content/xml/document/src/nsXMLContentSink.cpp
content/xml/document/src/nsXMLContentSink.h
content/xml/document/src/nsXMLDocument.cpp
parser/htmlparser/public/nsIContentSink.h
parser/htmlparser/src/nsParser.cpp
--- a/content/base/public/nsIDocument.h
+++ b/content/base/public/nsIDocument.h
@@ -1098,21 +1098,16 @@ public:
    * Enumerate the external resource documents associated with this document.
    * The enumerator callback should return PR_TRUE to continue enumerating, or
    * PR_FALSE to stop.  This callback will never get passed a null aDocument.
    */
   virtual void EnumerateExternalResources(nsSubDocEnumFunc aCallback,
                                           void* aData) = 0;
 
   /**
-   * Dispatch DOMContentLoaded and DOMFrameContentLoaded events
-   */
-  virtual void DispatchContentLoadedEvents() = 0;
-
-  /**
    * Return whether the document is currently showing (in the sense of
    * OnPageShow() having been called already and OnPageHide() not having been
    * called yet.
    */
   PRBool IsShowing() { return mIsShowing; }
 
 protected:
   ~nsIDocument()
--- a/content/base/src/nsContentSink.cpp
+++ b/content/base/src/nsContentSink.cpp
@@ -344,31 +344,29 @@ nsContentSink::ScriptAvailable(nsresult 
                                PRInt32 aLineNo)
 {
   PRUint32 count = mScriptElements.Count();
   if (mParser && NS_SUCCEEDED(aResult)) {
     // Only notify the parser about scripts that are actually going to run.
     mParser->ScriptExecuting();
   }
 
+  if (count == 0) {
+    return NS_OK;
+  }
+
   // aElement will not be in mScriptElements if a <script> was added
   // using the DOM during loading, or if the script was inline and thus
   // never blocked.
-  NS_ASSERTION(count == 0 ||
-               mScriptElements.IndexOf(aElement) == count - 1 ||
+  NS_ASSERTION(mScriptElements.IndexOf(aElement) == count - 1 ||
                mScriptElements.IndexOf(aElement) == PRUint32(-1),
                "script found at unexpected position");
 
   // Check if this is the element we were waiting for
-  if (count == 0 || aElement != mScriptElements[count - 1]) {
-    if (mDidGetReadyToCallDidBuildModelCall &&
-        !mScriptLoader->HasPendingOrCurrentScripts()) {
-      ContinueInterruptedParsingAsyncIfEnabled();
-    }
-
+  if (aElement != mScriptElements[count - 1]) {
     return NS_OK;
   }
 
   if (mParser && !mParser->IsParserEnabled()) {
     // make sure to unblock the parser before evaluating the script,
     // we must unblock the parser even if loading the script failed or
     // if the script was empty, if we don't, the parser will never be
     // unblocked.
@@ -384,17 +382,17 @@ nsContentSink::ScriptAvailable(nsresult 
       // Loading external script failed!. So, resume parsing since the parser
       // got blocked when loading external script. See
       // http://bugzilla.mozilla.org/show_bug.cgi?id=94903.
       //
       // XXX We don't resume parsing if we get NS_BINDING_ABORTED from the
       //     script load, assuming that that error code means that the user
       //     stopped the load through some action (like clicking a link). See
       //     http://bugzilla.mozilla.org/show_bug.cgi?id=243392.
-      ContinueInterruptedParsingAsyncIfEnabled();
+      ContinueInterruptedParsingAsync();
     }
   }
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsContentSink::ScriptEvaluated(nsresult aResult,
@@ -403,31 +401,29 @@ nsContentSink::ScriptEvaluated(nsresult 
 {
   if (mParser) {
     mParser->ScriptDidExecute();
   }
 
   // Check if this is the element we were waiting for
   PRInt32 count = mScriptElements.Count();
   if (count == 0 || aElement != mScriptElements[count - 1]) {
-    if (mDidGetReadyToCallDidBuildModelCall &&
-        !mScriptLoader->HasPendingOrCurrentScripts()) {
-      ContinueInterruptedParsingAsyncIfEnabled();
-    }
     return NS_OK;
   }
 
   // Pop the script element stack
   mScriptElements.RemoveObjectAt(count - 1); 
 
   if (NS_SUCCEEDED(aResult)) {
     PostEvaluateScript(aElement);
   }
 
-  ContinueInterruptedParsingAsyncIfEnabled();
+  if (mParser && mParser->IsParserEnabled()) {
+    ContinueInterruptedParsingAsync();
+  }
 
   return NS_OK;
 }
 
 nsresult
 nsContentSink::ProcessHTTPHeaders(nsIChannel* aChannel)
 {
   nsCOMPtr<nsIHttpChannel> httpchannel(do_QueryInterface(aChannel));
@@ -1740,37 +1736,22 @@ void
 nsContentSink::ContinueInterruptedParsingIfEnabled()
 {
   if (mParser && mParser->IsParserEnabled()) {
     mParser->ContinueInterruptedParsing();
   }
 }
 
 void
-nsContentSink::ContinueInterruptedParsingAsyncIfEnabled()
+nsContentSink::ContinueInterruptedParsingAsync()
 {
-  if (mParser && mParser->IsParserEnabled()) {
-    nsCOMPtr<nsIRunnable> ev = new nsRunnableMethod<nsContentSink>(this,
-      &nsContentSink::ContinueInterruptedParsingIfEnabled);
-
-    NS_DispatchToCurrentThread(ev);
-  }
-}
+  nsCOMPtr<nsIRunnable> ev = new nsRunnableMethod<nsContentSink>(this,
+    &nsContentSink::ContinueInterruptedParsingIfEnabled);
 
-PRBool
-nsContentSink::ReadyToCallDidBuildModelImpl()
-{
-  if (!mDidGetReadyToCallDidBuildModelCall) {
-    mDidGetReadyToCallDidBuildModelCall = PR_TRUE;
-
-    mDocument->DispatchContentLoadedEvents();
-    mScriptLoader->EndDeferringScripts();
-  }
-  
-  return !mScriptLoader->HasPendingOrCurrentScripts();
+  NS_DispatchToCurrentThread(ev);
 }
 
 // URIs: action, href, src, longdesc, usemap, cite
 PRBool 
 IsAttrURI(nsIAtom *aName)
 {
   return (aName == nsGkAtoms::action ||
           aName == nsGkAtoms::href ||
--- a/content/base/src/nsContentSink.h
+++ b/content/base/src/nsContentSink.h
@@ -132,17 +132,16 @@ class nsContentSink : public nsICSSLoade
 
   // nsIContentSink implementation helpers
   NS_HIDDEN_(nsresult) WillParseImpl(void);
   NS_HIDDEN_(nsresult) WillInterruptImpl(void);
   NS_HIDDEN_(nsresult) WillResumeImpl(void);
   NS_HIDDEN_(nsresult) DidProcessATokenImpl(void);
   NS_HIDDEN_(void) WillBuildModelImpl(void);
   NS_HIDDEN_(void) DidBuildModelImpl(void);
-  NS_HIDDEN_(PRBool) ReadyToCallDidBuildModelImpl(void);
   NS_HIDDEN_(void) DropParserAndPerfHint(void);
 
   void NotifyAppend(nsIContent* aContent, PRUint32 aStartIndex);
 
   // nsIDocumentObserver
   virtual void BeginUpdate(nsIDocument *aDocument, nsUpdateType aUpdateType);
   virtual void EndUpdate(nsIDocument *aDocument, nsUpdateType aUpdateType);
 
@@ -294,17 +293,17 @@ protected:
 
 private:
   // People shouldn't be allocating this class directly.  All subclasses should
   // be allocated using a zeroing operator new.
   void* operator new(size_t sz) CPP_THROW_NEW;  // Not to be implemented
 
 protected:
 
-  void ContinueInterruptedParsingAsyncIfEnabled();
+  void ContinueInterruptedParsingAsync();
   void ContinueInterruptedParsingIfEnabled();
 
   nsCOMPtr<nsIDocument>         mDocument;
   nsCOMPtr<nsIParser>           mParser;
   nsCOMPtr<nsIURI>              mDocumentURI;
   nsCOMPtr<nsIURI>              mDocumentBaseURI;
   nsCOMPtr<nsIDocShell>         mDocShell;
   nsCOMPtr<nsICSSLoader>        mCSSLoader;
@@ -345,17 +344,16 @@ protected:
   PRUint8 mDynamicLowerValue : 1;
   PRUint8 mParsing : 1;
   PRUint8 mDroppedTimer : 1;
   PRUint8 mChangeScrollPosWhenScrollingToRef : 1;
   // If true, we deferred starting layout until sheets load
   PRUint8 mDeferredLayoutStart : 1;
   // If true, we deferred notifications until sheets load
   PRUint8 mDeferredFlushTags : 1;
-  PRUint8 mDidGetReadyToCallDidBuildModelCall : 1;
   
   // -- Can interrupt parsing members --
   PRUint32 mDelayTimerStart;
 
   // Interrupt parsing during token procesing after # of microseconds
   PRInt32 mMaxTokenProcessingTime;
 
   // Switch between intervals when time is exceeded
--- a/content/base/src/nsDocument.cpp
+++ b/content/base/src/nsDocument.cpp
@@ -3949,16 +3949,20 @@ nsDocument::DispatchContentLoadedEvents(
           }
         }
       }
       
       parent = parent->GetParentDocument();
     } while (parent);
   }
 
+  if (mScriptLoader) {
+    mScriptLoader->EndDeferringScripts();
+  }
+
   UnblockOnload(PR_TRUE);
 }
 
 void
 nsDocument::EndLoad()
 {
   // Drop the ref to our parser, if any, but keep hold of the sink so that we
   // can flush it from FlushPendingNotifications as needed.  We might have to
@@ -3966,16 +3970,25 @@ nsDocument::EndLoad()
   if (mParser) {
     mWeakSink = do_GetWeakReference(mParser->GetContentSink());
     mParser = nsnull;
   }
   
   NS_DOCUMENT_NOTIFY_OBSERVERS(EndLoad, (this));
   
   SetReadyStateInternal(READYSTATE_INTERACTIVE);
+
+  if (!mSynchronousDOMContentLoaded) {
+    nsRefPtr<nsIRunnable> ev =
+      new nsRunnableMethod<nsDocument>(this,
+                                       &nsDocument::DispatchContentLoadedEvents);
+    NS_DispatchToCurrentThread(ev);
+  } else {
+    DispatchContentLoadedEvents();
+  }
 }
 
 void
 nsDocument::ContentStatesChanged(nsIContent* aContent1, nsIContent* aContent2,
                                  PRInt32 aStateMask)
 {
   NS_DOCUMENT_NOTIFY_OBSERVERS(ContentStatesChanged,
                                (this, aContent1, aContent2, aStateMask));
--- a/content/base/src/nsDocument.h
+++ b/content/base/src/nsDocument.h
@@ -973,17 +973,16 @@ public:
   virtual NS_HIDDEN_(void) TryCancelFrameLoaderInitialization(nsIDocShell* aShell);
   virtual NS_HIDDEN_(PRBool) FrameLoaderScheduledToBeFinalized(nsIDocShell* aShell);
   virtual NS_HIDDEN_(nsIDocument*)
     RequestExternalResource(nsIURI* aURI,
                             nsINode* aRequestingNode,
                             ExternalResourceLoad** aPendingLoad);
   virtual NS_HIDDEN_(void)
     EnumerateExternalResources(nsSubDocEnumFunc aCallback, void* aData);
-  virtual void DispatchContentLoadedEvents();
 
   NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(nsDocument, nsIDocument)
 
   /**
    * Utility method for getElementsByClassName.  aRootNode is the node (either
    * document or element), which getElementsByClassName was called on.
    */
   static nsresult GetElementsByClassNameHelper(nsINode* aRootNode,
@@ -1014,16 +1013,18 @@ protected:
   /**
    * Check that aId is not empty and log a message to the console
    * service if it is.
    * @returns PR_TRUE if aId looks correct, PR_FALSE otherwise.
    */
   static PRBool CheckGetElementByIdArg(const nsIAtom* aId);
   nsIdentifierMapEntry* GetElementByIdInternal(nsIAtom* aID);
 
+  void DispatchContentLoadedEvents();
+
   void RetrieveRelevantHeaders(nsIChannel *aChannel);
 
   static PRBool TryChannelCharset(nsIChannel *aChannel,
                                   PRInt32& aCharsetSource,
                                   nsACString& aCharset);
   
   void UpdateLinkMap();
   // Call this before the document does something that will unbind all content.
@@ -1169,16 +1170,18 @@ protected:
   // True if this document has ever had an HTML or SVG <title> element
   // bound to it
   PRPackedBool mMayHaveTitleElement:1;
 
   PRPackedBool mHasWarnedAboutBoxObjects:1;
 
   PRPackedBool mDelayFrameLoaderInitialization:1;
 
+  PRPackedBool mSynchronousDOMContentLoaded:1;
+
   // If true, we have an input encoding.  If this is false, then the
   // document was created entirely in memory
   PRPackedBool mHaveInputEncoding:1;
 
   PRUint8 mXMLDeclarationBits;
 
   PRUint8 mDefaultElementType;
 
--- a/content/base/src/nsScriptLoader.h
+++ b/content/base/src/nsScriptLoader.h
@@ -201,24 +201,16 @@ public:
    * queue.
    *
    * WARNING: This function will syncronously execute content scripts, so be
    * prepared that the world might change around you.
    */
   void EndDeferringScripts();
 
   /**
-   * Returns the number of pending scripts, deferred or not.
-   */
-  PRUint32 HasPendingOrCurrentScripts()
-  {
-    return mCurrentScript || GetFirstPendingRequest();
-  }
-
-  /**
    * Adds aURI to the preload list and starts loading it.
    *
    * @param aURI The URI of the external script.
    * @param aCharset The charset parameter for the script.
    * @param aType The type parameter for the script.
    */
   virtual void PreloadURI(nsIURI *aURI, const nsAString &aCharset,
                           const nsAString &aType);
--- a/content/base/test/Makefile.in
+++ b/content/base/test/Makefile.in
@@ -274,17 +274,16 @@ include $(topsrcdir)/config/rules.mk
 		test_bug455629.html \
 		bug455629-helper.svg \
 		test_bug473162-1.html \
 		test_bug473162-2.html \
 		test_XHRSendData.html \
 		file_XHRSendData.sjs \
 		file_XHRSendData_doc.xml \
 		file_XHRSendData_doc.xml^headers^ \
-		test_bug461555.html \
 		$(NULL)
 
 # Disabled for now. Mochitest isn't reliable enough for these.
 # test_bug444546.html \
 # bug444546.sjs \
 
 libs:: $(_TEST_FILES)
 	$(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/testing/mochitest/tests/$(relativesrcdir)
deleted file mode 100644
--- a/content/base/test/test_bug461555.html
+++ /dev/null
@@ -1,64 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<!--
-https://bugzilla.mozilla.org/show_bug.cgi?id=461555
--->
-<head>
-  <title>Test for Bug 461555</title>
-  <script type="application/javascript" src="/MochiKit/MochiKit.js"></script>
-  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
-  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
-</head>
-<body onload="done()">
-<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=461555">Mozilla Bug 461555</a>
-<p id="display"></p>
-<div id="content" style="display: none">
-  
-</div>
-<script>
-
-SimpleTest.waitForExplicitFinish();
-
-function writeIt(n) {
-  document.write("<span>" + n + "</span>");
-}
-
-var recur = 0;
-function externalScript() {
-  if (++recur == 3) {
-    return;
-  }
-
-  base = (recur-1) * 4
-
-  writeIt(7 + base);
-  s = document.createElement("script");
-  s.src = "data:text/plain,writeIt(" + (9+base) + ");writeIt(" + (10+base) + ");externalScript();";
-  document.body.appendChild(s);
-  writeIt(8 + base);
-}
-
-function done() {
-  nodes = document.getElementsByTagName('span');
-  is(nodes.length, 14, "wrong length");
-  for (i = 0; i < nodes.length; ++i) {
-    is(nodes[i].textContent, i+1, "wrong order");
-  }
-  SimpleTest.finish();
-}
-
-document.addEventListener("DOMContentLoaded", function() {
-  writeIt(3);
-}, false);
-
-writeIt(1);
-
-</script>
-<script defer>
-writeIt(4);
-</script>
-<script>
-writeIt(2);
-</script>
-<script defer src="data:text/plain,writeIt(5);writeIt(6);"></script>
-<script defer src="data:text/plain,externalScript();"></script>
--- a/content/html/document/src/nsHTMLContentSink.cpp
+++ b/content/html/document/src/nsHTMLContentSink.cpp
@@ -179,17 +179,16 @@ public:
 
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
 
   // nsIContentSink
   NS_IMETHOD WillParse(void);
   NS_IMETHOD WillBuildModel(void);
   NS_IMETHOD DidBuildModel(void);
-  virtual PRBool ReadyToCallDidBuildModel(void);
   NS_IMETHOD WillInterrupt(void);
   NS_IMETHOD WillResume(void);
   NS_IMETHOD SetParser(nsIParser* aParser);
   virtual void FlushPendingNotifications(mozFlushType aType);
   NS_IMETHOD SetDocumentCharset(nsACString& aCharset);
   virtual nsISupports *GetTarget();
 
   // nsIHTMLContentSink
@@ -1832,22 +1831,16 @@ HTMLContentSink::DidBuildModel(void)
   
   mDocument->EndLoad();
 
   DropParserAndPerfHint();
 
   return NS_OK;
 }
 
-PRBool
-HTMLContentSink::ReadyToCallDidBuildModel()
-{
-  return ReadyToCallDidBuildModelImpl();
-}
-
 NS_IMETHODIMP
 HTMLContentSink::SetParser(nsIParser* aParser)
 {
   NS_PRECONDITION(aParser, "Should have a parser here!");
   mParser = aParser;
   return NS_OK;
 }
 
--- a/content/xml/document/src/nsXMLContentSink.cpp
+++ b/content/xml/document/src/nsXMLContentSink.cpp
@@ -378,22 +378,16 @@ nsXMLContentSink::DidBuildModel()
     mDocument->EndLoad();
   }
 
   DropParserAndPerfHint();
 
   return NS_OK;
 }
 
-PRBool
-nsXMLContentSink::ReadyToCallDidBuildModel()
-{
-  return ReadyToCallDidBuildModelImpl();
-}
-
 NS_IMETHODIMP
 nsXMLContentSink::OnDocumentCreated(nsIDocument* aResultDocument)
 {
   NS_ENSURE_ARG(aResultDocument);
 
   nsCOMPtr<nsIContentViewer> contentViewer;
   mDocShell->GetContentViewer(getter_AddRefs(contentViewer));
   if (contentViewer) {
--- a/content/xml/document/src/nsXMLContentSink.h
+++ b/content/xml/document/src/nsXMLContentSink.h
@@ -88,17 +88,16 @@ public:
                                                      nsContentSink)
 
   NS_DECL_NSIEXPATSINK
 
   // nsIContentSink
   NS_IMETHOD WillParse(void);
   NS_IMETHOD WillBuildModel(void);
   NS_IMETHOD DidBuildModel(void);
-  virtual PRBool ReadyToCallDidBuildModel(void);
   NS_IMETHOD WillInterrupt(void);
   NS_IMETHOD WillResume(void);
   NS_IMETHOD SetParser(nsIParser* aParser);  
   virtual void FlushPendingNotifications(mozFlushType aType);
   NS_IMETHOD SetDocumentCharset(nsACString& aCharset);
   virtual nsISupports *GetTarget();
 
   // nsITransformObserver
--- a/content/xml/document/src/nsXMLDocument.cpp
+++ b/content/xml/document/src/nsXMLDocument.cpp
@@ -535,18 +535,20 @@ nsXMLDocument::StartDocumentLoad(const c
 }
 
 void
 nsXMLDocument::EndLoad()
 {
   mChannelIsPending = PR_FALSE;
   mLoopingForSyncLoad = PR_FALSE;
 
+  mSynchronousDOMContentLoaded = (mLoadedAsData || mLoadedAsInteractiveData);
   nsDocument::EndLoad();
-  if (mLoadedAsData || mLoadedAsInteractiveData) {
+  if (mSynchronousDOMContentLoaded) {
+    mSynchronousDOMContentLoaded = PR_FALSE;
     nsDocument::SetReadyStateInternal(nsIDocument::READYSTATE_COMPLETE);
     // Generate a document load event for the case when an XML
     // document was loaded as pure data without any presentation
     // attached to it.
     nsEvent event(PR_TRUE, NS_LOAD);
     nsEventDispatcher::Dispatch(static_cast<nsIDocument*>(this), nsnull,
                                 &event);
   }    
--- a/parser/htmlparser/public/nsIContentSink.h
+++ b/parser/htmlparser/public/nsIContentSink.h
@@ -51,18 +51,18 @@
  */
 #include "nsISupports.h"
 #include "nsStringGlue.h"
 #include "mozFlushType.h"
 
 class nsIParser;
 
 #define NS_ICONTENT_SINK_IID \
-{ 0xcfa3643b, 0xee60, 0x4bf0, \
-  { 0xbc, 0x83, 0x49, 0x95, 0xdb, 0xbc, 0xda, 0x75 } }
+{ 0x94ec4df1, 0x6885, 0x4b1f, \
+ { 0x85, 0x10, 0xe3, 0x5f, 0x4f, 0x36, 0xea, 0xaa } }
 
 class nsIContentSink : public nsISupports {
 public:
 
   NS_DECLARE_STATIC_IID_ACCESSOR(NS_ICONTENT_SINK_IID)
 
   /**
    * This method is called by the parser when it is entered from
@@ -84,22 +84,16 @@ public:
    * This method gets called when the parser concludes the process
    * of building the content model via the content sink.
    *
    * @update 5/7/98 gess
    */
   NS_IMETHOD DidBuildModel()=0;
 
   /**
-   * Thie method gets caller right before DidBuildModel is called.
-   * If false
-   */
-  virtual PRBool ReadyToCallDidBuildModel() { return PR_TRUE; };
-
-  /**
    * This method gets called when the parser gets i/o blocked,
    * and wants to notify the sink that it may be a while before
    * more data is available.
    *
    * @update 5/7/98 gess
    */
   NS_IMETHOD WillInterrupt(void)=0;
 
--- a/parser/htmlparser/src/nsParser.cpp
+++ b/parser/htmlparser/src/nsParser.cpp
@@ -1520,18 +1520,17 @@ nsParser::WillBuildModel(nsString& aFile
  */
 nsresult
 nsParser::DidBuildModel(nsresult anErrorCode)
 {
   nsresult result = anErrorCode;
 
   if (IsComplete()) {
     if (mParserContext && !mParserContext->mPrevContext) {
-      if (mParserContext->mDTD && mSink &&
-          mSink->ReadyToCallDidBuildModel()) {
+      if (mParserContext->mDTD) {
         result = mParserContext->mDTD->DidBuildModel(anErrorCode,PR_TRUE,this,mSink);
       }
 
       //Ref. to bug 61462.
       mParserContext->mRequest = 0;
     }
   }