When showing a document viewer, don't start layout on the documnt unless it's

already had layout started once.  Otherwise, just wait for the sink, or whoever
is responsible for it, to start layout once they're ready.  Bug 404470, r+sr=jst
This commit is contained in:
bzbarsky%mit.edu 2008-01-20 18:02:03 +00:00
Родитель 157b9a5774
Коммит 4cad7e3196
6 изменённых файлов: 34 добавлений и 21 удалений

Просмотреть файл

@ -96,9 +96,8 @@ struct JSObject;
// IID for the nsIDocument interface // IID for the nsIDocument interface
#define NS_IDOCUMENT_IID \ #define NS_IDOCUMENT_IID \
{ 0xed21686d, 0x4e2f, 0x41f5, \ { 0x626d86d2, 0x615f, 0x4a12, \
{ 0x94, 0xaa, 0xcc, 0x1f, 0xbd, 0xfa, 0x1f, 0x84 } } { 0x94, 0xd8, 0xe3, 0xdb, 0x3a, 0x29, 0x83, 0x72 } }
// Flag for AddStyleSheet(). // Flag for AddStyleSheet().
#define NS_STYLESHEET_FROM_CATALOG (1 << 0) #define NS_STYLESHEET_FROM_CATALOG (1 << 0)
@ -121,6 +120,7 @@ public:
mNodeInfoManager(nsnull), mNodeInfoManager(nsnull),
mCompatMode(eCompatibility_FullStandards), mCompatMode(eCompatibility_FullStandards),
mIsInitialDocumentInWindow(PR_FALSE), mIsInitialDocumentInWindow(PR_FALSE),
mMayStartLayout(PR_TRUE),
mPartID(0), mPartID(0),
mJSObject(nsnull) mJSObject(nsnull)
{ {
@ -151,6 +151,11 @@ public:
* @param aSink The content sink to use for the data. If this is null and * @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 * the document needs a content sink, it will create one based
* on whatever it knows about the data it's going to load. * 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, virtual nsresult StartDocumentLoad(const char* aCommand,
nsIChannel* aChannel, nsIChannel* aChannel,
@ -359,7 +364,9 @@ public:
/** /**
* Create a new presentation shell that will use aContext for its * Create a new presentation shell that will use aContext for its
* presentation context (presentation contexts <b>must not</b> be * presentation context (presentation contexts <b>must not</b> 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, virtual nsresult CreateShell(nsPresContext* aContext,
nsIViewManager* aViewManager, nsIViewManager* aViewManager,
@ -914,6 +921,16 @@ public:
return mLoadedAsData; return mLoadedAsData;
} }
PRBool MayStartLayout()
{
return mMayStartLayout;
}
void SetMayStartLayout(PRBool aMayStartLayout)
{
mMayStartLayout = aMayStartLayout;
}
JSObject* GetJSObject() const JSObject* GetJSObject() const
{ {
return mJSObject; return mJSObject;
@ -993,6 +1010,10 @@ protected:
// as scripts and plugins, disabled. // as scripts and plugins, disabled.
PRPackedBool mLoadedAsData; 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 // The bidi options for this document. What this bitfield means is
// defined in nsBidiUtils.h // defined in nsBidiUtils.h
PRUint32 mBidiOptions; PRUint32 mBidiOptions;

Просмотреть файл

@ -975,6 +975,7 @@ nsContentSink::StartLayout(PRBool aIgnorePendingSheets)
mLayoutStarted = PR_TRUE; mLayoutStarted = PR_TRUE;
mLastNotificationTime = PR_Now(); mLastNotificationTime = PR_Now();
mDocument->SetMayStartLayout(PR_TRUE);
nsPresShellIterator iter(mDocument); nsPresShellIterator iter(mDocument);
nsCOMPtr<nsIPresShell> shell; nsCOMPtr<nsIPresShell> shell;
while ((shell = iter.GetNextShell())) { while ((shell = iter.GetNextShell())) {
@ -995,10 +996,6 @@ nsContentSink::StartLayout(PRBool aIgnorePendingSheets)
continue; continue;
} }
// Make shell an observer for next time
shell->BeginObservingDocument();
// Resize-reflow this time
nsRect r = shell->GetPresContext()->GetVisibleArea(); nsRect r = shell->GetPresContext()->GetVisibleArea();
nsCOMPtr<nsIPresShell> shellGrip = shell; nsCOMPtr<nsIPresShell> shellGrip = shell;
nsresult rv = shell->InitialReflow(r.width, r.height); nsresult rv = shell->InitialReflow(r.width, r.height);

Просмотреть файл

@ -1453,6 +1453,8 @@ nsDocument::StartDocumentLoad(const char* aCommand, nsIChannel* aChannel,
CSSLoader()->SetEnabled(PR_FALSE); // Do not load/process styles when loading as data CSSLoader()->SetEnabled(PR_FALSE); // Do not load/process styles when loading as data
} }
mMayStartLayout = PR_FALSE;
if (aReset) { if (aReset) {
Reset(aChannel, aLoadGroup); Reset(aChannel, aLoadGroup);
} }

Просмотреть файл

@ -265,13 +265,10 @@ nsMediaDocument::CreateSyntheticDocument()
nsresult nsresult
nsMediaDocument::StartLayout() nsMediaDocument::StartLayout()
{ {
mMayStartLayout = PR_TRUE;
nsPresShellIterator iter(this); nsPresShellIterator iter(this);
nsCOMPtr<nsIPresShell> shell; nsCOMPtr<nsIPresShell> shell;
while ((shell = iter.GetNextShell())) { while ((shell = iter.GetNextShell())) {
// Make shell an observer for next time.
shell->BeginObservingDocument();
// Initial-reflow this time.
nsRect visibleArea = shell->GetPresContext()->GetVisibleArea(); nsRect visibleArea = shell->GetPresContext()->GetVisibleArea();
nsCOMPtr<nsIPresShell> shellGrip = shell; nsCOMPtr<nsIPresShell> shellGrip = shell;
nsresult rv = shell->InitialReflow(visibleArea.width, visibleArea.height); nsresult rv = shell->InitialReflow(visibleArea.width, visibleArea.height);

Просмотреть файл

@ -419,6 +419,7 @@ nsXULDocument::StartDocumentLoad(const char* aCommand, nsIChannel* aChannel,
// NOTE: If this ever starts calling nsDocument::StartDocumentLoad // NOTE: If this ever starts calling nsDocument::StartDocumentLoad
// we'll possibly need to reset our content type afterwards. // we'll possibly need to reset our content type afterwards.
mStillWalking = PR_TRUE; mStillWalking = PR_TRUE;
mMayStartLayout = PR_FALSE;
mDocumentLoadGroup = do_GetWeakReference(aLoadGroup); mDocumentLoadGroup = do_GetWeakReference(aLoadGroup);
mDocumentTitle.SetIsVoid(PR_TRUE); 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 // Make sure we're holding a strong ref to |shell| before we call
// InitialReflow() // InitialReflow()
nsCOMPtr<nsIPresShell> shellGrip = shell; nsCOMPtr<nsIPresShell> shellGrip = shell;
rv = shell->InitialReflow(r.width, r.height); rv = shell->InitialReflow(r.width, r.height);
NS_ENSURE_SUCCESS(rv, rv); 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; return NS_OK;

Просмотреть файл

@ -1917,7 +1917,8 @@ DocumentViewerImpl::Show(void)
if (mPresContext) { if (mPresContext) {
Hide(); 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 // If we get here the document load has already started and the