diff --git a/content/base/src/nsDocumentViewer.cpp b/content/base/src/nsDocumentViewer.cpp index b2ac92a7760..9781ff56128 100644 --- a/content/base/src/nsDocumentViewer.cpp +++ b/content/base/src/nsDocumentViewer.cpp @@ -1824,6 +1824,7 @@ DocumentViewerImpl::SetDOMDocument(nsIDOMDocument *aDocument) NS_IMETHODIMP DocumentViewerImpl::SetUAStyleSheet(nsIStyleSheet* aUAStyleSheet) { + NS_ASSERTION(aUAStyleSheet, "unexpected null pointer"); if (aUAStyleSheet) { nsCOMPtr sheet(do_QueryInterface(aUAStyleSheet)); nsCOMPtr newSheet; @@ -3838,14 +3839,15 @@ DocumentViewerImpl::ReflowPrintObject(PrintObject * aPO, PRBool aDoCalcShrink) } #endif // NS_PRINT_PREVIEW + nsCompatibility mode; + mPresContext->GetCompatibilityMode(&mode); + // Setup hierarchical relationship in view manager aPO->mViewManager->SetRootView(aPO->mRootView); aPO->mPresShell->Init(document, aPO->mPresContext, - aPO->mViewManager, aPO->mStyleSet); + aPO->mViewManager, aPO->mStyleSet, + mode != eCompatibility_Standard); - nsCompatibility mode; - mPresContext->GetCompatibilityMode(&mode); - aPO->mPresContext->SetCompatibilityMode(mode); if (!containerIsSet) { nsCOMPtr supps(do_QueryInterface(aPO->mWebShell)); aPO->mPresContext->SetContainer(supps); diff --git a/content/base/src/nsStyleSet.cpp b/content/base/src/nsStyleSet.cpp index dfdf41c317f..dfb535bf0a3 100644 --- a/content/base/src/nsStyleSet.cpp +++ b/content/base/src/nsStyleSet.cpp @@ -864,9 +864,23 @@ NS_IMETHODIMP StyleSetImpl::EnableQuirkStyleSheet(PRBool aEnable) } } } + NS_ASSERTION(mQuirkStyleSheet, "no quirk stylesheet"); if (mQuirkStyleSheet) { #if defined(DEBUG_warren) || defined(DEBUG_attinasi) printf( "%s Quirk StyleSheet\n", aEnable ? "Enabling" : "Disabling" ); +#endif +#ifdef DEBUG + PRUint32 count = 0; + if (mAgentRuleProcessors) + mAgentRuleProcessors->Count(&count); + PRBool enabledNow; + mQuirkStyleSheet->GetEnabled(enabledNow); + NS_ASSERTION(count == 0 || aEnable == enabledNow, + "enabling/disabling quirk stylesheet too late"); +#ifdef DEBUG_dbaron + if (count != 0 && aEnable == enabledNow) + printf("WARNING: We set the quirks mode too many times.\n"); // we do! +#endif #endif mQuirkStyleSheet->SetEnabled(aEnable); } diff --git a/content/html/document/src/nsHTMLDocument.cpp b/content/html/document/src/nsHTMLDocument.cpp index 1b90ef84821..006510c72da 100644 --- a/content/html/document/src/nsHTMLDocument.cpp +++ b/content/html/document/src/nsHTMLDocument.cpp @@ -495,17 +495,8 @@ nsHTMLDocument::CreateShell(nsIPresContext* aContext, nsIStyleSet* aStyleSet, nsIPresShell** aInstancePtrResult) { - nsresult result = nsMarkupDocument::CreateShell(aContext, - aViewManager, - aStyleSet, - aInstancePtrResult); - - if (NS_SUCCEEDED(result)) { - aContext->SetCompatibilityMode(((eDTDMode_strict== mDTDMode) ? - eCompatibility_Standard : - eCompatibility_NavQuirks)); - } - return result; + return doCreateShell(aContext, aViewManager, aStyleSet, + eDTDMode_strict != mDTDMode, aInstancePtrResult); } // The following Try*Charset will return PR_FALSE only if the charset source diff --git a/content/html/document/src/nsMarkupDocument.cpp b/content/html/document/src/nsMarkupDocument.cpp index b942f4fa3f8..0ee05f0c5d0 100644 --- a/content/html/document/src/nsMarkupDocument.cpp +++ b/content/html/document/src/nsMarkupDocument.cpp @@ -61,11 +61,22 @@ nsMarkupDocument::CreateShell(nsIPresContext* aContext, nsIViewManager* aViewManager, nsIStyleSet* aStyleSet, nsIPresShell** aInstancePtrResult) +{ + // Don't add anything here. Add it to |doCreateShell| instead. This + // exists so nsHTMLDocument can pass PR_TRUE for the 4th parameter + // some of the time. + return doCreateShell(aContext, aViewManager, aStyleSet, PR_FALSE, + aInstancePtrResult); +} + +nsresult +nsMarkupDocument::doCreateShell(nsIPresContext* aContext, + nsIViewManager* aViewManager, + nsIStyleSet* aStyleSet, + PRBool aIsQuirksMode, + nsIPresShell** aInstancePtrResult) { NS_PRECONDITION(nsnull != aInstancePtrResult, "null ptr"); - if (nsnull == aInstancePtrResult) { - return NS_ERROR_NULL_POINTER; - } nsresult rv; nsCOMPtr shell(do_CreateInstance(kPresShellCID,&rv)); @@ -73,7 +84,7 @@ nsMarkupDocument::CreateShell(nsIPresContext* aContext, return rv; } - rv = shell->Init(this, aContext, aViewManager, aStyleSet); + rv = shell->Init(this, aContext, aViewManager, aStyleSet, aIsQuirksMode); if (NS_FAILED(rv)) { return rv; } @@ -83,11 +94,6 @@ nsMarkupDocument::CreateShell(nsIPresContext* aContext, *aInstancePtrResult = shell.get(); NS_ADDREF(*aInstancePtrResult); - // tell the context the mode we want (always standard, which - // should be correct for everything except HTML) - // nsHTMLDocument overrides this method and sets it differently - aContext->SetCompatibilityMode(eCompatibility_Standard); - return NS_OK; } diff --git a/content/html/document/src/nsMarkupDocument.h b/content/html/document/src/nsMarkupDocument.h index 52fddec8a5a..83730ed99d7 100644 --- a/content/html/document/src/nsMarkupDocument.h +++ b/content/html/document/src/nsMarkupDocument.h @@ -62,6 +62,15 @@ public: nsIViewManager* aViewManager, nsIStyleSet* aStyleSet, nsIPresShell** aInstancePtrResult); +protected: + // To allow different implementations to choose the quirks mode + // differently for their |CreateShell| without overriding the whole + // thing. + nsresult doCreateShell(nsIPresContext* aContext, + nsIViewManager* aViewManager, + nsIStyleSet* aStyleSet, + PRBool aIsQuirksMode, + nsIPresShell** aInstancePtrResult); }; #endif /* nsMarkupDocument_h___ */ diff --git a/content/xul/document/src/nsXULDocument.cpp b/content/xul/document/src/nsXULDocument.cpp index b8b51d720db..be53541ad29 100644 --- a/content/xul/document/src/nsXULDocument.cpp +++ b/content/xul/document/src/nsXULDocument.cpp @@ -1053,19 +1053,14 @@ nsXULDocument::CreateShell(nsIPresContext* aContext, nsIPresShell** aInstancePtrResult) { NS_PRECONDITION(aInstancePtrResult, "null ptr"); - if (! aInstancePtrResult) - return NS_ERROR_NULL_POINTER; - - nsresult rv; nsIPresShell* shell; - if (NS_FAILED(rv = nsComponentManager::CreateInstance(kPresShellCID, - nsnull, - NS_GET_IID(nsIPresShell), - (void**) &shell))) + nsresult rv = CallCreateInstance(kPresShellCID, &shell); + if (NS_FAILED(rv)) return rv; - if (NS_FAILED(rv = shell->Init(this, aContext, aViewManager, aStyleSet))) { + rv = shell->Init(this, aContext, aViewManager, aStyleSet, PR_FALSE); + if (NS_FAILED(rv)) { NS_RELEASE(shell); return rv; } @@ -1073,9 +1068,6 @@ nsXULDocument::CreateShell(nsIPresContext* aContext, mPresShells.AppendElement(shell); *aInstancePtrResult = shell; // addref implicit in CreateInstance() - // tell the context the mode we want (always standard) - aContext->SetCompatibilityMode(eCompatibility_Standard); - return NS_OK; } diff --git a/layout/base/nsDocumentViewer.cpp b/layout/base/nsDocumentViewer.cpp index b2ac92a7760..9781ff56128 100644 --- a/layout/base/nsDocumentViewer.cpp +++ b/layout/base/nsDocumentViewer.cpp @@ -1824,6 +1824,7 @@ DocumentViewerImpl::SetDOMDocument(nsIDOMDocument *aDocument) NS_IMETHODIMP DocumentViewerImpl::SetUAStyleSheet(nsIStyleSheet* aUAStyleSheet) { + NS_ASSERTION(aUAStyleSheet, "unexpected null pointer"); if (aUAStyleSheet) { nsCOMPtr sheet(do_QueryInterface(aUAStyleSheet)); nsCOMPtr newSheet; @@ -3838,14 +3839,15 @@ DocumentViewerImpl::ReflowPrintObject(PrintObject * aPO, PRBool aDoCalcShrink) } #endif // NS_PRINT_PREVIEW + nsCompatibility mode; + mPresContext->GetCompatibilityMode(&mode); + // Setup hierarchical relationship in view manager aPO->mViewManager->SetRootView(aPO->mRootView); aPO->mPresShell->Init(document, aPO->mPresContext, - aPO->mViewManager, aPO->mStyleSet); + aPO->mViewManager, aPO->mStyleSet, + mode != eCompatibility_Standard); - nsCompatibility mode; - mPresContext->GetCompatibilityMode(&mode); - aPO->mPresContext->SetCompatibilityMode(mode); if (!containerIsSet) { nsCOMPtr supps(do_QueryInterface(aPO->mWebShell)); aPO->mPresContext->SetContainer(supps); diff --git a/layout/base/nsIPresShell.h b/layout/base/nsIPresShell.h index 4b41a604367..cc577ff8fa6 100644 --- a/layout/base/nsIPresShell.h +++ b/layout/base/nsIPresShell.h @@ -125,7 +125,8 @@ public: NS_IMETHOD Init(nsIDocument* aDocument, nsIPresContext* aPresContext, nsIViewManager* aViewManager, - nsIStyleSet* aStyleSet) = 0; + nsIStyleSet* aStyleSet, + PRBool aIsQuirksMode) = 0; /** * All callers are responsible for calling |Destroy| after calling diff --git a/layout/base/nsPresContext.cpp b/layout/base/nsPresContext.cpp index 608891d97b2..17649cf388a 100644 --- a/layout/base/nsPresContext.cpp +++ b/layout/base/nsPresContext.cpp @@ -150,7 +150,6 @@ nsPresContext::nsPresContext() { NS_INIT_REFCNT(); mCompatibilityMode = eCompatibility_Standard; - mCompatibilityLocked = PR_FALSE; mWidgetRenderingMode = eWidgetRendering_Gfx; mImageAnimationMode = imgIContainer::kNormalAnimMode; mImageAnimationModePref = imgIContainer::kNormalAnimMode; @@ -454,27 +453,6 @@ nsPresContext::GetUserPreferences() mFontScaler = prefInt; } - if (NS_SUCCEEDED(mPrefs->GetIntPref("nglayout.compatibility.mode", &prefInt))) { - // XXX this should really be a state on the webshell instead of using prefs - switch (prefInt) { - case 1: - mCompatibilityLocked = PR_TRUE; - mCompatibilityMode = eCompatibility_Standard; - break; - case 2: - mCompatibilityLocked = PR_TRUE; - mCompatibilityMode = eCompatibility_NavQuirks; - break; - case 0: // auto - default: - mCompatibilityLocked = PR_FALSE; - break; - } - } - else { - mCompatibilityLocked = PR_FALSE; // auto - } - if (NS_SUCCEEDED(mPrefs->GetIntPref("nglayout.widget.mode", &prefInt))) { mWidgetRenderingMode = (enum nsWidgetRendering)prefInt; // bad cast } @@ -783,18 +761,15 @@ nsPresContext::GetCompatibilityMode(nsCompatibility* aResult) NS_IMETHODIMP nsPresContext::SetCompatibilityMode(nsCompatibility aMode) { - if (! mCompatibilityLocked) { - mCompatibilityMode = aMode; - } + mCompatibilityMode = aMode; + + NS_ENSURE_TRUE(mShell, NS_OK); // enable/disable the QuirkSheet - NS_ASSERTION(mShell, "PresShell must be set on PresContext before calling nsPresContext::SetCompatibilityMode"); - if (mShell) { - nsCOMPtr set; - nsresult rv = mShell->GetStyleSet(getter_AddRefs(set)); - if (NS_SUCCEEDED(rv) && set) { - set->EnableQuirkStyleSheet((mCompatibilityMode != eCompatibility_Standard) ? PR_TRUE : PR_FALSE); - } + nsCOMPtr set; + mShell->GetStyleSet(getter_AddRefs(set)); + if (set) { + set->EnableQuirkStyleSheet(mCompatibilityMode != eCompatibility_Standard); } return NS_OK; } @@ -1477,6 +1452,8 @@ nsPresContext::LoadImage(const nsString& aURL, rv = content->GetDocument(*getter_AddRefs(document)); // If there is no document, skip the policy check + // XXXldb This really means the document is being destroyed, so + // perhaps we're better off skipping the load entirely. if (document) { nsCOMPtr globalScript; rv = document->GetScriptGlobalObject(getter_AddRefs(globalScript)); diff --git a/layout/base/nsPresShell.cpp b/layout/base/nsPresShell.cpp index 1f41cee5618..a5c4a9bff7d 100644 --- a/layout/base/nsPresShell.cpp +++ b/layout/base/nsPresShell.cpp @@ -1057,7 +1057,8 @@ public: NS_IMETHOD Init(nsIDocument* aDocument, nsIPresContext* aPresContext, nsIViewManager* aViewManager, - nsIStyleSet* aStyleSet); + nsIStyleSet* aStyleSet, + PRBool aIsQuirksMode); NS_IMETHOD Destroy(); NS_IMETHOD AllocateFrame(size_t aSize, void** aResult); @@ -1678,7 +1679,8 @@ NS_IMETHODIMP PresShell::Init(nsIDocument* aDocument, nsIPresContext* aPresContext, nsIViewManager* aViewManager, - nsIStyleSet* aStyleSet) + nsIStyleSet* aStyleSet, + PRBool aIsQuirksMode) { NS_PRECONDITION(nsnull != aDocument, "null ptr"); NS_PRECONDITION(nsnull != aPresContext, "null ptr"); @@ -1699,11 +1701,16 @@ PresShell::Init(nsIDocument* aDocument, mViewManager->SetViewObserver(this); // Bind the context to the presentation shell. - mPresContext = dont_QueryInterface(aPresContext); + mPresContext = aPresContext; aPresContext->SetShell(this); mStyleSet = aStyleSet; + // Set the compatibility mode after attaching the pres context and + // style set, but before creating any frames. + mPresContext->SetCompatibilityMode(aIsQuirksMode + ? eCompatibility_NavQuirks : eCompatibility_Standard); + mHistoryState = nsnull; nsresult result = nsComponentManager::CreateInstance(kFrameSelectionCID, nsnull, diff --git a/layout/base/public/nsIPresShell.h b/layout/base/public/nsIPresShell.h index 4b41a604367..cc577ff8fa6 100644 --- a/layout/base/public/nsIPresShell.h +++ b/layout/base/public/nsIPresShell.h @@ -125,7 +125,8 @@ public: NS_IMETHOD Init(nsIDocument* aDocument, nsIPresContext* aPresContext, nsIViewManager* aViewManager, - nsIStyleSet* aStyleSet) = 0; + nsIStyleSet* aStyleSet, + PRBool aIsQuirksMode) = 0; /** * All callers are responsible for calling |Destroy| after calling diff --git a/layout/base/src/nsPresContext.cpp b/layout/base/src/nsPresContext.cpp index 608891d97b2..17649cf388a 100644 --- a/layout/base/src/nsPresContext.cpp +++ b/layout/base/src/nsPresContext.cpp @@ -150,7 +150,6 @@ nsPresContext::nsPresContext() { NS_INIT_REFCNT(); mCompatibilityMode = eCompatibility_Standard; - mCompatibilityLocked = PR_FALSE; mWidgetRenderingMode = eWidgetRendering_Gfx; mImageAnimationMode = imgIContainer::kNormalAnimMode; mImageAnimationModePref = imgIContainer::kNormalAnimMode; @@ -454,27 +453,6 @@ nsPresContext::GetUserPreferences() mFontScaler = prefInt; } - if (NS_SUCCEEDED(mPrefs->GetIntPref("nglayout.compatibility.mode", &prefInt))) { - // XXX this should really be a state on the webshell instead of using prefs - switch (prefInt) { - case 1: - mCompatibilityLocked = PR_TRUE; - mCompatibilityMode = eCompatibility_Standard; - break; - case 2: - mCompatibilityLocked = PR_TRUE; - mCompatibilityMode = eCompatibility_NavQuirks; - break; - case 0: // auto - default: - mCompatibilityLocked = PR_FALSE; - break; - } - } - else { - mCompatibilityLocked = PR_FALSE; // auto - } - if (NS_SUCCEEDED(mPrefs->GetIntPref("nglayout.widget.mode", &prefInt))) { mWidgetRenderingMode = (enum nsWidgetRendering)prefInt; // bad cast } @@ -783,18 +761,15 @@ nsPresContext::GetCompatibilityMode(nsCompatibility* aResult) NS_IMETHODIMP nsPresContext::SetCompatibilityMode(nsCompatibility aMode) { - if (! mCompatibilityLocked) { - mCompatibilityMode = aMode; - } + mCompatibilityMode = aMode; + + NS_ENSURE_TRUE(mShell, NS_OK); // enable/disable the QuirkSheet - NS_ASSERTION(mShell, "PresShell must be set on PresContext before calling nsPresContext::SetCompatibilityMode"); - if (mShell) { - nsCOMPtr set; - nsresult rv = mShell->GetStyleSet(getter_AddRefs(set)); - if (NS_SUCCEEDED(rv) && set) { - set->EnableQuirkStyleSheet((mCompatibilityMode != eCompatibility_Standard) ? PR_TRUE : PR_FALSE); - } + nsCOMPtr set; + mShell->GetStyleSet(getter_AddRefs(set)); + if (set) { + set->EnableQuirkStyleSheet(mCompatibilityMode != eCompatibility_Standard); } return NS_OK; } @@ -1477,6 +1452,8 @@ nsPresContext::LoadImage(const nsString& aURL, rv = content->GetDocument(*getter_AddRefs(document)); // If there is no document, skip the policy check + // XXXldb This really means the document is being destroyed, so + // perhaps we're better off skipping the load entirely. if (document) { nsCOMPtr globalScript; rv = document->GetScriptGlobalObject(getter_AddRefs(globalScript)); diff --git a/layout/base/src/nsPresContext.h b/layout/base/src/nsPresContext.h index ddf20d4038b..92f6cce13fb 100644 --- a/layout/base/src/nsPresContext.h +++ b/layout/base/src/nsPresContext.h @@ -262,7 +262,6 @@ protected: nsCOMPtr mBaseURL; nsCompatibility mCompatibilityMode; - PRPackedBool mCompatibilityLocked; nsWidgetRendering mWidgetRenderingMode; PRPackedBool mImageAnimationStopped; // image animation stopped diff --git a/layout/html/base/src/nsPresShell.cpp b/layout/html/base/src/nsPresShell.cpp index 1f41cee5618..a5c4a9bff7d 100644 --- a/layout/html/base/src/nsPresShell.cpp +++ b/layout/html/base/src/nsPresShell.cpp @@ -1057,7 +1057,8 @@ public: NS_IMETHOD Init(nsIDocument* aDocument, nsIPresContext* aPresContext, nsIViewManager* aViewManager, - nsIStyleSet* aStyleSet); + nsIStyleSet* aStyleSet, + PRBool aIsQuirksMode); NS_IMETHOD Destroy(); NS_IMETHOD AllocateFrame(size_t aSize, void** aResult); @@ -1678,7 +1679,8 @@ NS_IMETHODIMP PresShell::Init(nsIDocument* aDocument, nsIPresContext* aPresContext, nsIViewManager* aViewManager, - nsIStyleSet* aStyleSet) + nsIStyleSet* aStyleSet, + PRBool aIsQuirksMode) { NS_PRECONDITION(nsnull != aDocument, "null ptr"); NS_PRECONDITION(nsnull != aPresContext, "null ptr"); @@ -1699,11 +1701,16 @@ PresShell::Init(nsIDocument* aDocument, mViewManager->SetViewObserver(this); // Bind the context to the presentation shell. - mPresContext = dont_QueryInterface(aPresContext); + mPresContext = aPresContext; aPresContext->SetShell(this); mStyleSet = aStyleSet; + // Set the compatibility mode after attaching the pres context and + // style set, but before creating any frames. + mPresContext->SetCompatibilityMode(aIsQuirksMode + ? eCompatibility_NavQuirks : eCompatibility_Standard); + mHistoryState = nsnull; nsresult result = nsComponentManager::CreateInstance(kFrameSelectionCID, nsnull, diff --git a/layout/style/nsStyleSet.cpp b/layout/style/nsStyleSet.cpp index dfdf41c317f..dfb535bf0a3 100644 --- a/layout/style/nsStyleSet.cpp +++ b/layout/style/nsStyleSet.cpp @@ -864,9 +864,23 @@ NS_IMETHODIMP StyleSetImpl::EnableQuirkStyleSheet(PRBool aEnable) } } } + NS_ASSERTION(mQuirkStyleSheet, "no quirk stylesheet"); if (mQuirkStyleSheet) { #if defined(DEBUG_warren) || defined(DEBUG_attinasi) printf( "%s Quirk StyleSheet\n", aEnable ? "Enabling" : "Disabling" ); +#endif +#ifdef DEBUG + PRUint32 count = 0; + if (mAgentRuleProcessors) + mAgentRuleProcessors->Count(&count); + PRBool enabledNow; + mQuirkStyleSheet->GetEnabled(enabledNow); + NS_ASSERTION(count == 0 || aEnable == enabledNow, + "enabling/disabling quirk stylesheet too late"); +#ifdef DEBUG_dbaron + if (count != 0 && aEnable == enabledNow) + printf("WARNING: We set the quirks mode too many times.\n"); // we do! +#endif #endif mQuirkStyleSheet->SetEnabled(aEnable); }