diff --git a/content/base/public/nsIDocument.h b/content/base/public/nsIDocument.h
index 9056a617fc4..05c04555395 100644
--- a/content/base/public/nsIDocument.h
+++ b/content/base/public/nsIDocument.h
@@ -96,9 +96,8 @@ struct JSObject;
// IID for the nsIDocument interface
#define NS_IDOCUMENT_IID \
-{ 0xed21686d, 0x4e2f, 0x41f5, \
- { 0x94, 0xaa, 0xcc, 0x1f, 0xbd, 0xfa, 0x1f, 0x84 } }
-
+{ 0x626d86d2, 0x615f, 0x4a12, \
+ { 0x94, 0xd8, 0xe3, 0xdb, 0x3a, 0x29, 0x83, 0x72 } }
// Flag for AddStyleSheet().
#define NS_STYLESHEET_FROM_CATALOG (1 << 0)
@@ -121,6 +120,7 @@ public:
mNodeInfoManager(nsnull),
mCompatMode(eCompatibility_FullStandards),
mIsInitialDocumentInWindow(PR_FALSE),
+ mMayStartLayout(PR_TRUE),
mPartID(0),
mJSObject(nsnull)
{
@@ -151,6 +151,11 @@ public:
* @param aSink The content sink to use for the data. If this is null and
* the document needs a content sink, it will create one based
* on whatever it knows about the data it's going to load.
+ *
+ * Once this has been called, the document will return false for
+ * MayStartLayout() until SetMayStartLayout(PR_TRUE) is called on it. Making
+ * sure this happens is the responsibility of the caller of
+ * StartDocumentLoad().
*/
virtual nsresult StartDocumentLoad(const char* aCommand,
nsIChannel* aChannel,
@@ -359,7 +364,9 @@ public:
/**
* Create a new presentation shell that will use aContext for its
* presentation context (presentation contexts must not be
- * shared among multiple presentation shells).
+ * shared among multiple presentation shells). The caller of this
+ * method is responsible for calling BeginObservingDocument() on the
+ * presshell if the presshell should observe document mutations.
*/
virtual nsresult CreateShell(nsPresContext* aContext,
nsIViewManager* aViewManager,
@@ -914,6 +921,16 @@ public:
return mLoadedAsData;
}
+ PRBool MayStartLayout()
+ {
+ return mMayStartLayout;
+ }
+
+ void SetMayStartLayout(PRBool aMayStartLayout)
+ {
+ mMayStartLayout = aMayStartLayout;
+ }
+
JSObject* GetJSObject() const
{
return mJSObject;
@@ -993,6 +1010,10 @@ protected:
// as scripts and plugins, disabled.
PRPackedBool mLoadedAsData;
+ // If true, whoever is creating the document has gotten it to the
+ // point where it's safe to start layout on it.
+ PRPackedBool mMayStartLayout;
+
// The bidi options for this document. What this bitfield means is
// defined in nsBidiUtils.h
PRUint32 mBidiOptions;
diff --git a/content/base/src/nsContentSink.cpp b/content/base/src/nsContentSink.cpp
index d1b669ea93d..5edc698fb4e 100644
--- a/content/base/src/nsContentSink.cpp
+++ b/content/base/src/nsContentSink.cpp
@@ -975,6 +975,7 @@ nsContentSink::StartLayout(PRBool aIgnorePendingSheets)
mLayoutStarted = PR_TRUE;
mLastNotificationTime = PR_Now();
+ mDocument->SetMayStartLayout(PR_TRUE);
nsPresShellIterator iter(mDocument);
nsCOMPtr shell;
while ((shell = iter.GetNextShell())) {
@@ -995,10 +996,6 @@ nsContentSink::StartLayout(PRBool aIgnorePendingSheets)
continue;
}
- // Make shell an observer for next time
- shell->BeginObservingDocument();
-
- // Resize-reflow this time
nsRect r = shell->GetPresContext()->GetVisibleArea();
nsCOMPtr shellGrip = shell;
nsresult rv = shell->InitialReflow(r.width, r.height);
diff --git a/content/base/src/nsDocument.cpp b/content/base/src/nsDocument.cpp
index f94e35b90f3..6b8df78cc54 100644
--- a/content/base/src/nsDocument.cpp
+++ b/content/base/src/nsDocument.cpp
@@ -1453,6 +1453,8 @@ nsDocument::StartDocumentLoad(const char* aCommand, nsIChannel* aChannel,
CSSLoader()->SetEnabled(PR_FALSE); // Do not load/process styles when loading as data
}
+ mMayStartLayout = PR_FALSE;
+
if (aReset) {
Reset(aChannel, aLoadGroup);
}
diff --git a/content/html/document/src/nsMediaDocument.cpp b/content/html/document/src/nsMediaDocument.cpp
index 6bf66039d5d..20df54534d5 100644
--- a/content/html/document/src/nsMediaDocument.cpp
+++ b/content/html/document/src/nsMediaDocument.cpp
@@ -265,13 +265,10 @@ nsMediaDocument::CreateSyntheticDocument()
nsresult
nsMediaDocument::StartLayout()
{
+ mMayStartLayout = PR_TRUE;
nsPresShellIterator iter(this);
nsCOMPtr shell;
while ((shell = iter.GetNextShell())) {
- // Make shell an observer for next time.
- shell->BeginObservingDocument();
-
- // Initial-reflow this time.
nsRect visibleArea = shell->GetPresContext()->GetVisibleArea();
nsCOMPtr shellGrip = shell;
nsresult rv = shell->InitialReflow(visibleArea.width, visibleArea.height);
diff --git a/content/xul/document/src/nsXULDocument.cpp b/content/xul/document/src/nsXULDocument.cpp
index 968be892fb1..0f26898c7c7 100644
--- a/content/xul/document/src/nsXULDocument.cpp
+++ b/content/xul/document/src/nsXULDocument.cpp
@@ -419,6 +419,7 @@ nsXULDocument::StartDocumentLoad(const char* aCommand, nsIChannel* aChannel,
// NOTE: If this ever starts calling nsDocument::StartDocumentLoad
// we'll possibly need to reset our content type afterwards.
mStillWalking = PR_TRUE;
+ mMayStartLayout = PR_FALSE;
mDocumentLoadGroup = do_GetWeakReference(aLoadGroup);
mDocumentTitle.SetIsVoid(PR_TRUE);
@@ -1932,19 +1933,13 @@ nsXULDocument::StartLayout(void)
}
}
+ mMayStartLayout = PR_TRUE;
+
// Make sure we're holding a strong ref to |shell| before we call
// InitialReflow()
nsCOMPtr shellGrip = shell;
rv = shell->InitialReflow(r.width, r.height);
NS_ENSURE_SUCCESS(rv, rv);
-
- // Start observing the document _after_ we do the initial
- // reflow. Otherwise, we'll get into an trouble trying to
- // create kids before the root frame is established.
- // XXXbz why is that an issue here and not in nsContentSink or
- // nsDocumentViewer? Perhaps we should just flush the way
- // nsDocumentViewer does?
- shell->BeginObservingDocument();
}
return NS_OK;
diff --git a/layout/base/nsDocumentViewer.cpp b/layout/base/nsDocumentViewer.cpp
index d047c1792eb..25e6b16a914 100644
--- a/layout/base/nsDocumentViewer.cpp
+++ b/layout/base/nsDocumentViewer.cpp
@@ -1917,7 +1917,8 @@ DocumentViewerImpl::Show(void)
if (mPresContext) {
Hide();
- rv = InitPresentationStuff(PR_TRUE, PR_TRUE);
+ rv = InitPresentationStuff(mDocument->MayStartLayout(),
+ mDocument->MayStartLayout());
}
// If we get here the document load has already started and the