diff --git a/mozilla/content/base/src/nsDocumentViewer.cpp b/mozilla/content/base/src/nsDocumentViewer.cpp index de6a7aed964..2a02d87d4d0 100644 --- a/mozilla/content/base/src/nsDocumentViewer.cpp +++ b/mozilla/content/base/src/nsDocumentViewer.cpp @@ -275,17 +275,17 @@ struct PrintObject public: PrintObject(); - virtual ~PrintObject(); + ~PrintObject(); // non-virtual // Methods PRBool IsPrintable() { return !mDontPrint; } nsIWebShell *mWebShell; PrintObjectType mFrameType; - nsIPresContext *mPresContext; - nsIStyleSet *mStyleSet; - nsIPresShell *mPresShell; - nsIViewManager *mViewManager; + nsCOMPtr mPresContext; + nsCOMPtr mStyleSet; + nsCOMPtr mPresShell; + nsCOMPtr mViewManager; nsIView *mView; nsIView *mRootView; @@ -305,6 +305,9 @@ public: nsRect mClipRect; +private: + PrintObject& operator=(const PrintObject& aOther); // not implemented + }; //--------------------------------------------------- @@ -314,17 +317,17 @@ struct PrintData { public: PrintData(); - virtual ~PrintData(); + ~PrintData(); // non-virtual // Listener Helper Methods void OnEndPrinting(nsresult aResult); void OnStartPrinting(); - nsIDeviceContext *mPrintDC; - nsIPresContext *mPrintPC; - nsIStyleSet *mPrintSS; - nsIPresShell *mPrintPS; - nsIViewManager *mPrintVM; + nsCOMPtr mPrintDC; + nsCOMPtr mPrintPC; + nsCOMPtr mPrintSS; + nsCOMPtr mPrintPS; + nsCOMPtr mPrintVM; nsIView *mPrintView; FILE *mFilePointer; // a file where information can go to when printing @@ -351,6 +354,9 @@ public: FILE * mDebugFD; #endif +private: + PrintData& operator=(const PrintData& aOther); // not implemented + }; //------------------------------------------------------------- @@ -372,30 +378,7 @@ public: NS_DECL_ISUPPORTS // nsIContentViewer interface... - NS_IMETHOD Init(nsIWidget* aParentWidget, - nsIDeviceContext* aDeviceContext, - const nsRect& aBounds); - NS_IMETHOD SetContainer(nsISupports* aContainer); - NS_IMETHOD GetContainer(nsISupports** aContainerResult); - NS_IMETHOD LoadStart(nsISupports* aDoc); - NS_IMETHOD LoadComplete(nsresult aStatus); - NS_IMETHOD Unload(void); - NS_IMETHOD Destroy(void); - NS_IMETHOD Stop(void); - NS_IMETHOD GetDOMDocument(nsIDOMDocument **aResult); - NS_IMETHOD SetDOMDocument(nsIDOMDocument *aDocument); - NS_IMETHOD GetBounds(nsRect& aResult); - NS_IMETHOD SetBounds(const nsRect& aBounds); - - NS_IMETHOD GetPreviousViewer(nsIContentViewer** aResult); - NS_IMETHOD SetPreviousViewer(nsIContentViewer* aViewer); - - NS_IMETHOD Move(PRInt32 aX, PRInt32 aY); - NS_IMETHOD Show(); - NS_IMETHOD Hide(); - NS_IMETHOD Validate(); - NS_IMETHOD SetEnableRendering(PRBool aOn); - NS_IMETHOD GetEnableRendering(PRBool* aResult); + NS_DECL_NSICONTENTVIEWER // nsIDocumentViewer interface... NS_IMETHOD SetUAStyleSheet(nsIStyleSheet* aUAStyleSheet); @@ -667,9 +650,7 @@ private: PrintObject * mPrintObj; }; -NS_IMPL_ADDREF(nsPagePrintTimer) -NS_IMPL_RELEASE(nsPagePrintTimer) -NS_IMPL_QUERY_INTERFACE1(nsPagePrintTimer, nsITimerCallback) +NS_IMPL_ISUPPORTS1(nsPagePrintTimer, nsITimerCallback) nsresult NS_NewUpdateTimer(nsPagePrintTimer **aResult) { @@ -690,7 +671,6 @@ nsresult NS_NewUpdateTimer(nsPagePrintTimer **aResult) //-- PrintData Class Impl //--------------------------------------------------- PrintData::PrintData() : - mPrintDC(nsnull), mPrintPC(nsnull), mPrintSS(nsnull), mPrintPS(nsnull), mPrintVM(nsnull), mPrintView(nsnull), mFilePointer(nsnull), mPrintObject(nsnull), mSelectedPO(nsnull), mPrintDocList(nsnull), mIsIFrameSelected(PR_FALSE), mIsParentAFrameSet(PR_FALSE), mPrintingAsIsSubDoc(PR_FALSE), @@ -708,7 +688,9 @@ PrintData::~PrintData() // printing is complete, clean up now if (mPrintPS) { + // XXX we never call BeginObservingDocument on this pres shell. mPrintPS->EndObservingDocument(); + mPrintPS->Destroy(); } OnEndPrinting(NS_OK); // removes listener @@ -725,12 +707,6 @@ PrintData::~PrintData() mPrintDocList->Clear(); delete mPrintDocList; - NS_IF_RELEASE(mPrintPS); - NS_IF_RELEASE(mPrintVM); - NS_IF_RELEASE(mPrintSS); - NS_IF_RELEASE(mPrintDC); - NS_IF_RELEASE(mPrintPC); - #ifdef DEBUG_PRINTING fclose(mDebugFD); #endif @@ -754,7 +730,7 @@ void PrintData::OnEndPrinting(nsresult aResult) } mPrintListener->OnEndPrinting(aResult); // clear the lister so the destructor doesn't send the - mPrintListener = do_QueryInterface(nsnull); + mPrintListener = nsnull; } } @@ -763,8 +739,7 @@ void PrintData::OnEndPrinting(nsresult aResult) //-- PrintObject Class Impl //--------------------------------------------------- PrintObject::PrintObject() : - mWebShell(nsnull), mFrameType(eFrame), mPresContext(nsnull), - mStyleSet(nsnull), mPresShell(nsnull), mViewManager(nsnull), + mWebShell(nsnull), mFrameType(eFrame), mView(nsnull), mRootView(nsnull), mContent(nsnull), mSeqFrame(nsnull), mPageFrame(nsnull), mPageNum(-1), mRect(0,0,0,0), mReflowRect(0,0,0,0), @@ -776,16 +751,13 @@ PrintObject::PrintObject() : PrintObject::~PrintObject() { - NS_IF_RELEASE(mPresShell); - NS_IF_RELEASE(mStyleSet); - NS_IF_RELEASE(mViewManager); - NS_IF_RELEASE(mPresContext); - for (PRInt32 i=0;iDestroy(); } //------------------------------------------------------------------ @@ -809,7 +781,7 @@ NS_NewDocumentViewer(nsIDocumentViewer** aResult) *aResult = nsnull; return NS_ERROR_OUT_OF_MEMORY; } - return it->QueryInterface(NS_GET_IID(nsIDocumentViewer), (void**) aResult); + return CallQueryInterface(it, aResult); } // Note: operator new zeros our memory @@ -828,7 +800,7 @@ void DocumentViewerImpl::PrepareToStartLoad() { } DocumentViewerImpl::DocumentViewerImpl(nsIPresContext* aPresContext) - : mPresContext(dont_QueryInterface(aPresContext)) + : mPresContext(aPresContext) { NS_INIT_ISUPPORTS(); mHintCharsetSource = kCharsetUninitialized; @@ -845,20 +817,16 @@ NS_IMPL_ISUPPORTS5(DocumentViewerImpl, DocumentViewerImpl::~DocumentViewerImpl() { - if (mPagePrintTimer != nsnull) { - mPagePrintTimer->Stop(); - delete mPagePrintTimer; - } - - if (mPrt != nsnull) { - mPrt->OnEndPrinting(NS_ERROR_FAILURE); - delete mPrt; - } - // Revoke pending invalidate events - NS_ASSERTION(!mDocument, "User did not call nsIContentViewer::Destroy"); + NS_ASSERTION(!mDocument, "User did not call nsIContentViewer::Close"); if (mDocument) + Close(); + + NS_ASSERTION(!mPresShell, "User did not call nsIContentViewer::Destroy"); + if (mPresShell) Destroy(); + // XXX(?) Revoke pending invalidate events + // clear weak references before we go away if (mPresContext) { mPresContext->SetContainer(nsnull); @@ -870,10 +838,6 @@ DocumentViewerImpl::~DocumentViewerImpl() // stop everything but the chrome. mPresContext->Stop(); } - - // Avoid leaking the old viewer. - if (mPreviousViewer) - SetPreviousViewer(nsnull); } /* @@ -1037,7 +1001,7 @@ DocumentViewerImpl::Init(nsIWidget* aParentWidget, // this is the owning reference. The nsCOMPtr will take care of releasing // our ref to the listener on destruction. NS_ADDREF(selectionListener); - rv = selectionListener->QueryInterface(NS_GET_IID(nsISelectionListener), getter_AddRefs(mSelectionListener)); + mSelectionListener = do_QueryInterface(selectionListener); NS_RELEASE(selectionListener); if (NS_FAILED(rv)) return rv; @@ -1060,7 +1024,7 @@ DocumentViewerImpl::Init(nsIWidget* aParentWidget, // this is the owning reference. The nsCOMPtr will take care of releasing // our ref to the listener on destruction. NS_ADDREF(focusListener); - rv = focusListener->QueryInterface(NS_GET_IID(nsIDOMFocusListener), getter_AddRefs(mFocusListener)); + mFocusListener = do_QueryInterface(focusListener); NS_RELEASE(focusListener); if (NS_FAILED(rv)) return rv; @@ -1068,8 +1032,7 @@ DocumentViewerImpl::Init(nsIWidget* aParentWidget, if(mDocument) { // get the DOM event receiver - nsCOMPtr erP; - rv = mDocument->QueryInterface(NS_GET_IID(nsIDOMEventReceiver), getter_AddRefs(erP)); + nsCOMPtr erP (do_QueryInterface(mDocument, &rv)); if(NS_FAILED(rv) || !erP) return rv?rv:NS_ERROR_FAILURE; @@ -1166,13 +1129,19 @@ DocumentViewerImpl::Unload() } NS_IMETHODIMP -DocumentViewerImpl::Destroy() +DocumentViewerImpl::Close() { - // All callers are supposed to call destroy to break circular + // All callers are supposed to call close to break circular // references. If we do this stuff in the destructor, the // destructor might never be called (especially if we're being // used from JS. + // Close is also needed to disable scripts during paint suppression, + // since we transfer the existing global object to the new document + // that is loaded. In the future, the global object may become a proxy + // for an object that can be switched in and out so that we don't need + // to disable scripts during paint suppression. + nsresult rv; if (mDocument) { @@ -1187,13 +1156,41 @@ DocumentViewerImpl::Destroy() mDocument->SetScriptGlobalObject(nsnull); if (mFocusListener) { // get the DOM event receiver - nsCOMPtr erP; - rv = mDocument->QueryInterface(NS_GET_IID(nsIDOMEventReceiver), getter_AddRefs(erP)); + nsCOMPtr erP( do_QueryInterface(mDocument, &rv) ); if(NS_SUCCEEDED(rv) && erP) erP->RemoveEventListenerByIID(mFocusListener, NS_GET_IID(nsIDOMFocusListener)); } } + mDocument = nsnull; + return NS_OK; +} + +NS_IMETHODIMP +DocumentViewerImpl::Destroy() +{ + // All callers are supposed to call destroy to break circular + // references. If we do this stuff in the destructor, the + // destructor might never be called (especially if we're being + // used from JS. + + if (mPagePrintTimer != nsnull) { + mPagePrintTimer->Stop(); + delete mPagePrintTimer; + } + + if (mPrt) { + mPrt->OnEndPrinting(NS_ERROR_FAILURE); + delete mPrt; + mPrt = nsnull; + } + + // Avoid leaking the old viewer. + if (mPreviousViewer) { + mPreviousViewer->Destroy(); + mPreviousViewer = nsnull; + } + if (mDeviceContext) mDeviceContext->FlushFontCache(); @@ -1201,13 +1198,14 @@ DocumentViewerImpl::Destroy() // Break circular reference (or something) mPresShell->EndObservingDocument(); nsCOMPtr selection; - rv = GetDocumentSelection(getter_AddRefs(selection)); + nsresult rv = GetDocumentSelection(getter_AddRefs(selection)); nsCOMPtr selPrivate(do_QueryInterface(selection)); if (NS_SUCCEEDED(rv) && selPrivate && mSelectionListener) selPrivate->RemoveSelectionListener(mSelectionListener); + mPresShell->Destroy(); + mPresShell = nsnull; } - mDocument = nsnull; return NS_OK; } @@ -1291,6 +1289,7 @@ DocumentViewerImpl::SetDOMDocument(nsIDOMDocument *aDocument) // 3) Replace the current pres shell with a new shell for the new document mPresShell->EndObservingDocument(); + mPresShell->Destroy(); mPresShell = nsnull; rv = newDoc->CreateShell(mPresContext, mViewManager, styleSet, @@ -1302,8 +1301,7 @@ DocumentViewerImpl::SetDOMDocument(nsIDOMDocument *aDocument) // 4) Register the focus listener on the new document if(mDocument) { - nsCOMPtr erP; - rv = mDocument->QueryInterface(NS_GET_IID(nsIDOMEventReceiver), getter_AddRefs(erP)); + nsCOMPtr erP = do_QueryInterface(mDocument, &rv); if(NS_FAILED(rv) || !erP) return rv ? rv : NS_ERROR_FAILURE; @@ -1370,17 +1368,13 @@ DocumentViewerImpl::GetPreviousViewer(nsIContentViewer** aViewer) NS_IMETHODIMP DocumentViewerImpl::SetPreviousViewer(nsIContentViewer* aViewer) { - if (!aViewer) { - // Clearing it out. - mPreviousViewer = nsnull; + // NOTE: |Show| sets |mPreviousViewer| to null without calling this + // function. + + if (aViewer) { + NS_ASSERTION(!mPreviousViewer, + "can't set previous viewer when there already is one"); - // Now we can show, but only if we aren't dead already (which - // can occasionally happen when one page moves to another during the onload - // handler.) - if (mDocument) - Show(); - } - else { // In a multiple chaining situation (which occurs when running a thrashing // test like i-bench or jrgm's tests with no delay), we can build up a // whole chain of viewers. In order to avoid this, we always set our previous @@ -1392,9 +1386,9 @@ DocumentViewerImpl::SetPreviousViewer(nsIContentViewer* aViewer) nsCOMPtr prevViewer; aViewer->GetPreviousViewer(getter_AddRefs(prevViewer)); if (prevViewer) { - SetPreviousViewer(prevViewer); - prevViewer->SetPreviousViewer(nsnull); - return NS_OK; + aViewer->SetPreviousViewer(nsnull); + aViewer->Destroy(); + return SetPreviousViewer(prevViewer); } } @@ -1432,6 +1426,17 @@ DocumentViewerImpl::Show(void) { NS_ENSURE_TRUE(mDocument, NS_ERROR_NOT_AVAILABLE); NS_PRECONDITION(mWindow, "null window"); + + // We don't need the previous viewer anymore since we're not + // displaying it. + if (mPreviousViewer) { + // This little dance *may* only be to keep + // PresShell::EndObservingDocument happy, but I'm not sure. + nsCOMPtr prevViewer(mPreviousViewer); + mPreviousViewer = nsnull; + prevViewer->Destroy(); + } + if (mWindow) { mWindow->Show(PR_TRUE); } @@ -1491,7 +1496,7 @@ GetPresShellFor(nsIDocShell* aDocShell) aDocShell->GetContentViewer(&cv); if (nsnull != cv) { nsIDocumentViewer* docv = nsnull; - cv->QueryInterface(NS_GET_IID(nsIDocumentViewer), (void**) &docv); + CallQueryInterface(cv, &docv); if (nsnull != docv) { nsIPresContext* cx; docv->GetPresContext(cx); @@ -1537,7 +1542,7 @@ static void DumpFrames(FILE* out, nsAutoString tmp; nsIFrameDebug* frameDebug; - if (NS_SUCCEEDED(child->QueryInterface(NS_GET_IID(nsIFrameDebug), (void**)&frameDebug))) { + if (NS_SUCCEEDED(CallQueryInterface(child, &frameDebug))) { frameDebug->GetFrameName(tmp); } fputs(tmp, out); @@ -1665,7 +1670,7 @@ static void DumpPrintObjectsList(nsVoidArray * aDocList, FILE* aFD = nsnull) po->mPresShell->GetRootFrame(&rootFrame); while (rootFrame != nsnull) { nsIPageSequenceFrame * sqf = nsnull; - if (NS_SUCCEEDED(rootFrame->QueryInterface(NS_GET_IID(nsIPageSequenceFrame), (void**)&sqf)) && sqf) { + if (NS_SUCCEEDED(CallQueryInterface(rootFrame, &sqf)) && sqf) { break; } rootFrame->FirstChild(po->mPresContext, nsnull, &rootFrame); @@ -1721,7 +1726,7 @@ static void DumpPrintObjectsTreeLayout(PrintObject * aPO, } if (fd) { nsIFrame* rootFrame = nsnull; - if (aPO->mPresShell != nsnull) { + if (aPO->mPresShell) { aPO->mPresShell->GetRootFrame(&rootFrame); } for (PRInt32 k=0;kQueryInterface(NS_GET_IID(nsIFrame), (void **)&seqFrame))) { + if (NS_FAILED(CallQueryInterface(aPageSeqFrame, &seqFrame))) { return NS_ERROR_FAILURE; } @@ -2268,7 +2273,7 @@ DocumentViewerImpl::PrintPage(nsIPresContext* aPresContext, // page num of it's parent doc curPageSeq->GetCurrentPageNum(&pageNum); nsIFrame* fr; - curPageSeq->QueryInterface(NS_GET_IID(nsIFrame), (void**)&fr); + CallQueryInterface(curPageSeq, &fr); if (fr == po->mSeqFrame && pageNum == po->mPageNum) { PRBool donePrintingSubDoc; @@ -2425,7 +2430,7 @@ void DocumentViewerImpl::CalcPageFrameLocation(nsIPresShell * aPresShell, // Keep a pointer to the Seq and Page frames nsIPageSequenceFrame * sqf = nsnull; if (parent != nsnull && - NS_SUCCEEDED(parent->QueryInterface(NS_GET_IID(nsIPageSequenceFrame), (void**)&sqf)) && sqf) { + NS_SUCCEEDED(CallQueryInterface(parent, &sqf)) && sqf) { pageFrame = temp; seqFrame = parent; } @@ -2482,7 +2487,7 @@ DocumentViewerImpl::MapSubDocFrameLocations(PrintObject* aPO) CalcPageFrameLocation(aPO->mParent->mPresShell, aPO); } - if (aPO->mPresShell != nsnull) { + if (aPO->mPresShell) { for (PRInt32 i=0;imKids.Count();i++) { MapSubDocFrameLocations((PrintObject*)aPO->mKids[i]); } @@ -2732,7 +2737,7 @@ DocumentViewerImpl::ReflowPrintObject(PrintObject * aPO) if (NS_FAILED(rv)) { return rv; } else { - rv = printcon->QueryInterface(NS_GET_IID(nsIPresContext), (void**)&aPO->mPresContext); + aPO->mPresContext = do_QueryInterface(printcon); if (NS_FAILED(rv)) { return rv; } @@ -2741,16 +2746,14 @@ DocumentViewerImpl::ReflowPrintObject(PrintObject * aPO) // init it with the DC (aPO->mPresContext)->Init(mPrt->mPrintDocDC); - CreateStyleSet(document, &aPO->mStyleSet); + CreateStyleSet(document, getter_AddRefs(aPO->mStyleSet)); - rv = nsComponentManager::CreateInstance(kPresShellCID,nsnull, - NS_GET_IID(nsIPresShell),(void **)&aPO->mPresShell); + aPO->mPresShell = do_CreateInstance(kPresShellCID, &rv); if (NS_FAILED(rv)) { return rv; } - rv = nsComponentManager::CreateInstance(kViewManagerCID,nsnull, - NS_GET_IID(nsIViewManager),(void **)&aPO->mViewManager); + aPO->mViewManager = do_CreateInstance(kViewManagerCID, &rv); if (NS_FAILED(rv)) { return rv; } @@ -2796,7 +2799,7 @@ DocumentViewerImpl::ReflowPrintObject(PrintObject * aPO) nsRect tbounds = nsRect(0, 0, width, height); // Create a child window of the parent that is our "root view/window" - rv = nsComponentManager::CreateInstance(kViewCID, nsnull, NS_GET_IID(nsIView), (void **)&(aPO->mRootView)); + rv = CallCreateInstance(kViewCID, &aPO->mRootView); if (NS_FAILED(rv)) { return rv; } @@ -2807,7 +2810,8 @@ DocumentViewerImpl::ReflowPrintObject(PrintObject * aPO) // Setup hierarchical relationship in view manager aPO->mViewManager->SetRootView(aPO->mRootView); - aPO->mPresShell->Init(document, aPO->mPresContext, aPO->mViewManager,aPO->mStyleSet); + aPO->mPresShell->Init(document, aPO->mPresContext, + aPO->mViewManager, aPO->mStyleSet); nsCompatibility mode; mPresContext->GetCompatibilityMode(&mode); @@ -3435,7 +3439,7 @@ DocumentViewerImpl::DoPrint(PrintObject * aPO, PRBool aDoSyncPrinting, PRBool& a nsIFrame* root; poPresShell->GetRootFrame(&root); - if (NS_SUCCEEDED(root->QueryInterface(NS_GET_IID(nsIFrameDebug), (void**) &fdbg))) { + if (NS_SUCCEEDED(CallQueryInterface(root, &fdbg))) { fdbg->DumpRegressionData(poPresContext, mPrt->mFilePointer, 0, PR_TRUE); } fclose(mPrt->mFilePointer); @@ -3501,7 +3505,7 @@ DocumentViewerImpl::DoPrint(PrintObject * aPO, PRBool aDoSyncPrinting, PRBool& a if (startPageNum == endPageNum) { nsIFrame * seqFrame; - if (NS_FAILED(pageSequence->QueryInterface(NS_GET_IID(nsIFrame), (void **)&seqFrame))) { + if (NS_FAILED(CallQueryInterface(pageSequence, &seqFrame))) { gCurrentlyPrinting = PR_FALSE; return NS_ERROR_FAILURE; } @@ -3518,7 +3522,7 @@ DocumentViewerImpl::DoPrint(PrintObject * aPO, PRBool aDoSyncPrinting, PRBool& a } nsIFrame * seqFrame; - if (NS_FAILED(pageSequence->QueryInterface(NS_GET_IID(nsIFrame), (void **)&seqFrame))) { + if (NS_FAILED(CallQueryInterface(pageSequence, &seqFrame))) { gCurrentlyPrinting = PR_FALSE; return NS_ERROR_FAILURE; } @@ -3582,11 +3586,13 @@ DocumentViewerImpl::CalcNumPrintableDocsAndPages(PRInt32& aNumDocs, PRInt32& aNu PrintObject* po = (PrintObject*)mPrt->mPrintDocList->ElementAt(i); NS_ASSERTION(po, "PrintObject can't be null!"); if (po->IsPrintable()) { - if (po->mPresShell != nsnull && (po->mFrameType != eIFrame && po->mFrameType != eFrameSet)) { + if (po->mPresShell && + po->mFrameType != eIFrame && + po->mFrameType != eFrameSet) { nsIPageSequenceFrame* pageSequence; po->mPresShell->GetPageSequenceFrame(&pageSequence); nsIFrame * seqFrame; - if (NS_SUCCEEDED(pageSequence->QueryInterface(NS_GET_IID(nsIFrame), (void **)&seqFrame))) { + if (NS_SUCCEEDED(CallQueryInterface(pageSequence, &seqFrame))) { nsIFrame* frame; seqFrame->FirstChild(po->mPresContext, nsnull, &frame); while (frame) { @@ -3765,7 +3771,7 @@ DocumentViewerImpl::CreateStyleSet(nsIDocument* aDocument, NS_WARNING("unable to load UA style sheet"); } - rv = nsComponentManager::CreateInstance(kStyleSetCID,nsnull,NS_GET_IID(nsIStyleSet),(void**)aStyleSet); + rv = CallCreateInstance(kStyleSetCID, aStyleSet); if (NS_OK == rv) { PRInt32 index = 0; aDocument->GetNumberOfStyleSheets(&index); @@ -3838,10 +3844,9 @@ DocumentViewerImpl::MakeWindow(nsIWidget* aParentWidget, { nsresult rv; - rv = nsComponentManager::CreateInstance(kViewManagerCID, - nsnull, - NS_GET_IID(nsIViewManager), - getter_AddRefs(mViewManager)); + mViewManager = do_CreateInstance(kViewManagerCID, &rv); + if (NS_FAILED(rv)) + return rv; nsCOMPtr dx; mPresContext->GetDeviceContext(getter_AddRefs(dx)); @@ -3852,11 +3857,12 @@ DocumentViewerImpl::MakeWindow(nsIWidget* aParentWidget, mPresContext->GetPixelsToTwips(&p2t); tbounds *= p2t; - // Initialize the view manager with an offset. This allows the viewmanager - // to manage a coordinate space offset from (0,0) - if ((NS_OK != rv) || (NS_OK != mViewManager->Init(dx, tbounds.x, tbounds.y))) { + // Initialize the view manager with an offset. This allows the viewmanager + // to manage a coordinate space offset from (0,0) + rv = mViewManager->Init(dx, tbounds.x, tbounds.y); + if (NS_FAILED(rv)) return rv; - } + // Reset the bounds offset so the root view is set to 0,0. The offset is // specified in nsIViewManager::Init above. // Besides, layout will reset the root view to (0,0) during reflow, @@ -3867,15 +3873,12 @@ DocumentViewerImpl::MakeWindow(nsIWidget* aParentWidget, // Create a child window of the parent that is our "root view/window" // Create a view - rv = nsComponentManager::CreateInstance(kViewCID, - nsnull, - NS_GET_IID(nsIView), - (void**)&mView); - if ((NS_OK != rv) || (NS_OK != mView->Init(mViewManager, - tbounds, - nsnull))) { + rv = CallCreateInstance(kViewCID, &mView); + if (NS_FAILED(rv)) + return rv; + rv = mView->Init(mViewManager, tbounds, nsnull); + if (NS_FAILED(rv)) return rv; - } rv = mView->CreateWidget(kWidgetCID, nsnull, aParentWidget->GetNativeData(NS_NATIVE_WIDGET)); @@ -4064,10 +4067,7 @@ NS_IMETHODIMP DocumentViewerImpl::SelectAll() if (NS_FAILED(rv)) return rv; static NS_DEFINE_CID(kCDOMRangeCID, NS_RANGE_CID); - nsCOMPtr range; - rv = nsComponentManager::CreateInstance(kCDOMRangeCID, nsnull, - NS_GET_IID(nsIDOMRange), - getter_AddRefs(range)); + nsCOMPtr range = do_CreateInstance(kCDOMRangeCID, &rv); rv = range->SelectNodeContents(bodyNode); if (NS_FAILED(rv)) return rv; @@ -4320,10 +4320,7 @@ nsresult rv; // another is still in here (the printing dialog is a good example). if(gCurrentlyPrinting) { // Beep at the user, let them know we are not ready to print. - nsCOMPtr soundInterface; - rv = nsComponentManager::CreateInstance(kSoundCID, - nsnull, NS_GET_IID(nsISound), - getter_AddRefs(soundInterface)); + nsCOMPtr soundInterface( do_CreateInstance(kSoundCID, &rv) ); if (NS_SUCCEEDED(rv) && (soundInterface != nsnull)){ soundInterface->Beep(); } @@ -4425,11 +4422,8 @@ nsresult rv; } #endif - nsCOMPtr factory; - nsComponentManager::CreateInstance(kDeviceContextSpecFactoryCID, - nsnull, - NS_GET_IID(nsIDeviceContextSpecFactory), - (void **)getter_AddRefs(factory)); + nsCOMPtr factory = + do_CreateInstance(kDeviceContextSpecFactoryCID); if (factory) { @@ -4439,13 +4433,13 @@ nsresult rv; nsIDeviceContextSpec *devspec = nsnull; nsCOMPtr dx; - mPrt->mPrintDC = nsnull; + mPrt->mPrintDC = nsnull; // XXX why? mPrt->mFilePointer = aFile; factory->CreateDeviceContextSpec(mWindow, devspec, aSilent); if (nsnull != devspec) { mPresContext->GetDeviceContext(getter_AddRefs(dx)); - rv = dx->GetDeviceContextFor(devspec, mPrt->mPrintDC); + rv = dx->GetDeviceContextFor(devspec, *getter_AddRefs(mPrt->mPrintDC)); if (NS_SUCCEEDED(rv)) { NS_RELEASE(devspec); @@ -4457,7 +4451,7 @@ nsresult rv; gCurrentlyPrinting = PR_FALSE; return rv; } else { - rv = printcon->QueryInterface(NS_GET_IID(nsIPresContext), (void**)&mPrt->mPrintPC); + mPrt->mPrintPC = do_QueryInterface(printcon, &rv); if (NS_FAILED(rv)) { gCurrentlyPrinting = PR_FALSE; return rv; @@ -4478,15 +4472,15 @@ nsresult rv; mPrt->mPrintPC->Init(mPrt->mPrintDC); mPrt->mPrintPC->SetContainer(webContainer); - CreateStyleSet(mDocument,&mPrt->mPrintSS); + CreateStyleSet(mDocument, getter_AddRefs(mPrt->mPrintSS)); - rv = nsComponentManager::CreateInstance(kPresShellCID, nsnull, NS_GET_IID(nsIPresShell),(void**)&mPrt->mPrintPS); + mPrt->mPrintPS = do_CreateInstance(kPresShellCID, &rv); if(NS_FAILED(rv)){ gCurrentlyPrinting = PR_FALSE; return rv; } - rv = nsComponentManager::CreateInstance(kViewManagerCID, nsnull, NS_GET_IID(nsIViewManager),(void**)&mPrt->mPrintVM); + mPrt->mPrintVM = do_CreateInstance(kViewManagerCID, &rv); if(NS_FAILED(rv)) { gCurrentlyPrinting = PR_FALSE; return rv; @@ -4498,7 +4492,7 @@ nsresult rv; return rv; } - rv = nsComponentManager::CreateInstance(kViewCID, nsnull, NS_GET_IID(nsIView),(void**)&mPrt->mPrintView); + rv = CallCreateInstance(kViewCID, &mPrt->mPrintView); if(NS_FAILED(rv)) { gCurrentlyPrinting = PR_FALSE; return rv; @@ -5146,7 +5140,7 @@ NS_IMETHODIMP DocumentViewerImpl::SizeToContent() #pragma mark - #endif -NS_IMPL_ISUPPORTS(nsDocViewerSelectionListener, NS_GET_IID(nsISelectionListener)); +NS_IMPL_ISUPPORTS1(nsDocViewerSelectionListener, nsISelectionListener); nsresult nsDocViewerSelectionListener::Init(DocumentViewerImpl *aDocViewer) { @@ -5368,7 +5362,7 @@ NS_IMETHODIMP nsDocViewerSelectionListener::NotifySelectionChanged(nsIDOMDocumen } //nsDocViewerFocusListener -NS_IMPL_ISUPPORTS(nsDocViewerFocusListener, NS_GET_IID(nsIDOMFocusListener)); +NS_IMPL_ISUPPORTS1(nsDocViewerFocusListener, nsIDOMFocusListener); nsDocViewerFocusListener::nsDocViewerFocusListener() :mDocViewer(nsnull) diff --git a/mozilla/docshell/base/nsDocShell.cpp b/mozilla/docshell/base/nsDocShell.cpp index 04c47b0dd33..74cce7a6253 100644 --- a/mozilla/docshell/base/nsDocShell.cpp +++ b/mozilla/docshell/base/nsDocShell.cpp @@ -2451,6 +2451,7 @@ nsDocShell::Destroy() docShellParentAsNode->RemoveChild(this); if (mContentViewer) { + mContentViewer->Close(); mContentViewer->Destroy(); mContentViewer = nsnull; } @@ -4106,7 +4107,7 @@ nsDocShell::SetupNewViewer(nsIContentViewer * aNewViewer) } } - mContentViewer->Destroy(); + mContentViewer->Close(); aNewViewer->SetPreviousViewer(mContentViewer); mContentViewer = nsnull; } diff --git a/mozilla/docshell/base/nsIContentViewer.idl b/mozilla/docshell/base/nsIContentViewer.idl index de6e6b39807..f6d85a30568 100644 --- a/mozilla/docshell/base/nsIContentViewer.idl +++ b/mozilla/docshell/base/nsIContentViewer.idl @@ -27,7 +27,17 @@ interface nsIContentViewer : nsISupports void loadComplete(in unsigned long aStatus); void unload(); + /** + * All users of a content viewer are responsible for calling both + * close() and destroy(), in that order. + * + * close() should be called when the load of a new page for the next + * content viewer begins, and destroy() should be called when the next + * content viewer replaces this one. + */ + void close(); void destroy(); + void stop(); attribute nsIDOMDocument DOMDocument; @@ -35,8 +45,11 @@ interface nsIContentViewer : nsISupports [noscript] void getBounds(in nsRectRef aBounds); [noscript] void setBounds([const] in nsRectRef aBounds); - [noscript] void setPreviousViewer(in nsIContentViewer aViewer); - [noscript] nsIContentViewer getPreviousViewer(); + /** + * The previous content viewer, which has been |close|d but not + * |destroy|ed. + */ + [noscript] attribute nsIContentViewer previousViewer; void move(in long aX, in long aY); diff --git a/mozilla/layout/base/nsDocumentViewer.cpp b/mozilla/layout/base/nsDocumentViewer.cpp index de6a7aed964..2a02d87d4d0 100644 --- a/mozilla/layout/base/nsDocumentViewer.cpp +++ b/mozilla/layout/base/nsDocumentViewer.cpp @@ -275,17 +275,17 @@ struct PrintObject public: PrintObject(); - virtual ~PrintObject(); + ~PrintObject(); // non-virtual // Methods PRBool IsPrintable() { return !mDontPrint; } nsIWebShell *mWebShell; PrintObjectType mFrameType; - nsIPresContext *mPresContext; - nsIStyleSet *mStyleSet; - nsIPresShell *mPresShell; - nsIViewManager *mViewManager; + nsCOMPtr mPresContext; + nsCOMPtr mStyleSet; + nsCOMPtr mPresShell; + nsCOMPtr mViewManager; nsIView *mView; nsIView *mRootView; @@ -305,6 +305,9 @@ public: nsRect mClipRect; +private: + PrintObject& operator=(const PrintObject& aOther); // not implemented + }; //--------------------------------------------------- @@ -314,17 +317,17 @@ struct PrintData { public: PrintData(); - virtual ~PrintData(); + ~PrintData(); // non-virtual // Listener Helper Methods void OnEndPrinting(nsresult aResult); void OnStartPrinting(); - nsIDeviceContext *mPrintDC; - nsIPresContext *mPrintPC; - nsIStyleSet *mPrintSS; - nsIPresShell *mPrintPS; - nsIViewManager *mPrintVM; + nsCOMPtr mPrintDC; + nsCOMPtr mPrintPC; + nsCOMPtr mPrintSS; + nsCOMPtr mPrintPS; + nsCOMPtr mPrintVM; nsIView *mPrintView; FILE *mFilePointer; // a file where information can go to when printing @@ -351,6 +354,9 @@ public: FILE * mDebugFD; #endif +private: + PrintData& operator=(const PrintData& aOther); // not implemented + }; //------------------------------------------------------------- @@ -372,30 +378,7 @@ public: NS_DECL_ISUPPORTS // nsIContentViewer interface... - NS_IMETHOD Init(nsIWidget* aParentWidget, - nsIDeviceContext* aDeviceContext, - const nsRect& aBounds); - NS_IMETHOD SetContainer(nsISupports* aContainer); - NS_IMETHOD GetContainer(nsISupports** aContainerResult); - NS_IMETHOD LoadStart(nsISupports* aDoc); - NS_IMETHOD LoadComplete(nsresult aStatus); - NS_IMETHOD Unload(void); - NS_IMETHOD Destroy(void); - NS_IMETHOD Stop(void); - NS_IMETHOD GetDOMDocument(nsIDOMDocument **aResult); - NS_IMETHOD SetDOMDocument(nsIDOMDocument *aDocument); - NS_IMETHOD GetBounds(nsRect& aResult); - NS_IMETHOD SetBounds(const nsRect& aBounds); - - NS_IMETHOD GetPreviousViewer(nsIContentViewer** aResult); - NS_IMETHOD SetPreviousViewer(nsIContentViewer* aViewer); - - NS_IMETHOD Move(PRInt32 aX, PRInt32 aY); - NS_IMETHOD Show(); - NS_IMETHOD Hide(); - NS_IMETHOD Validate(); - NS_IMETHOD SetEnableRendering(PRBool aOn); - NS_IMETHOD GetEnableRendering(PRBool* aResult); + NS_DECL_NSICONTENTVIEWER // nsIDocumentViewer interface... NS_IMETHOD SetUAStyleSheet(nsIStyleSheet* aUAStyleSheet); @@ -667,9 +650,7 @@ private: PrintObject * mPrintObj; }; -NS_IMPL_ADDREF(nsPagePrintTimer) -NS_IMPL_RELEASE(nsPagePrintTimer) -NS_IMPL_QUERY_INTERFACE1(nsPagePrintTimer, nsITimerCallback) +NS_IMPL_ISUPPORTS1(nsPagePrintTimer, nsITimerCallback) nsresult NS_NewUpdateTimer(nsPagePrintTimer **aResult) { @@ -690,7 +671,6 @@ nsresult NS_NewUpdateTimer(nsPagePrintTimer **aResult) //-- PrintData Class Impl //--------------------------------------------------- PrintData::PrintData() : - mPrintDC(nsnull), mPrintPC(nsnull), mPrintSS(nsnull), mPrintPS(nsnull), mPrintVM(nsnull), mPrintView(nsnull), mFilePointer(nsnull), mPrintObject(nsnull), mSelectedPO(nsnull), mPrintDocList(nsnull), mIsIFrameSelected(PR_FALSE), mIsParentAFrameSet(PR_FALSE), mPrintingAsIsSubDoc(PR_FALSE), @@ -708,7 +688,9 @@ PrintData::~PrintData() // printing is complete, clean up now if (mPrintPS) { + // XXX we never call BeginObservingDocument on this pres shell. mPrintPS->EndObservingDocument(); + mPrintPS->Destroy(); } OnEndPrinting(NS_OK); // removes listener @@ -725,12 +707,6 @@ PrintData::~PrintData() mPrintDocList->Clear(); delete mPrintDocList; - NS_IF_RELEASE(mPrintPS); - NS_IF_RELEASE(mPrintVM); - NS_IF_RELEASE(mPrintSS); - NS_IF_RELEASE(mPrintDC); - NS_IF_RELEASE(mPrintPC); - #ifdef DEBUG_PRINTING fclose(mDebugFD); #endif @@ -754,7 +730,7 @@ void PrintData::OnEndPrinting(nsresult aResult) } mPrintListener->OnEndPrinting(aResult); // clear the lister so the destructor doesn't send the - mPrintListener = do_QueryInterface(nsnull); + mPrintListener = nsnull; } } @@ -763,8 +739,7 @@ void PrintData::OnEndPrinting(nsresult aResult) //-- PrintObject Class Impl //--------------------------------------------------- PrintObject::PrintObject() : - mWebShell(nsnull), mFrameType(eFrame), mPresContext(nsnull), - mStyleSet(nsnull), mPresShell(nsnull), mViewManager(nsnull), + mWebShell(nsnull), mFrameType(eFrame), mView(nsnull), mRootView(nsnull), mContent(nsnull), mSeqFrame(nsnull), mPageFrame(nsnull), mPageNum(-1), mRect(0,0,0,0), mReflowRect(0,0,0,0), @@ -776,16 +751,13 @@ PrintObject::PrintObject() : PrintObject::~PrintObject() { - NS_IF_RELEASE(mPresShell); - NS_IF_RELEASE(mStyleSet); - NS_IF_RELEASE(mViewManager); - NS_IF_RELEASE(mPresContext); - for (PRInt32 i=0;iDestroy(); } //------------------------------------------------------------------ @@ -809,7 +781,7 @@ NS_NewDocumentViewer(nsIDocumentViewer** aResult) *aResult = nsnull; return NS_ERROR_OUT_OF_MEMORY; } - return it->QueryInterface(NS_GET_IID(nsIDocumentViewer), (void**) aResult); + return CallQueryInterface(it, aResult); } // Note: operator new zeros our memory @@ -828,7 +800,7 @@ void DocumentViewerImpl::PrepareToStartLoad() { } DocumentViewerImpl::DocumentViewerImpl(nsIPresContext* aPresContext) - : mPresContext(dont_QueryInterface(aPresContext)) + : mPresContext(aPresContext) { NS_INIT_ISUPPORTS(); mHintCharsetSource = kCharsetUninitialized; @@ -845,20 +817,16 @@ NS_IMPL_ISUPPORTS5(DocumentViewerImpl, DocumentViewerImpl::~DocumentViewerImpl() { - if (mPagePrintTimer != nsnull) { - mPagePrintTimer->Stop(); - delete mPagePrintTimer; - } - - if (mPrt != nsnull) { - mPrt->OnEndPrinting(NS_ERROR_FAILURE); - delete mPrt; - } - // Revoke pending invalidate events - NS_ASSERTION(!mDocument, "User did not call nsIContentViewer::Destroy"); + NS_ASSERTION(!mDocument, "User did not call nsIContentViewer::Close"); if (mDocument) + Close(); + + NS_ASSERTION(!mPresShell, "User did not call nsIContentViewer::Destroy"); + if (mPresShell) Destroy(); + // XXX(?) Revoke pending invalidate events + // clear weak references before we go away if (mPresContext) { mPresContext->SetContainer(nsnull); @@ -870,10 +838,6 @@ DocumentViewerImpl::~DocumentViewerImpl() // stop everything but the chrome. mPresContext->Stop(); } - - // Avoid leaking the old viewer. - if (mPreviousViewer) - SetPreviousViewer(nsnull); } /* @@ -1037,7 +1001,7 @@ DocumentViewerImpl::Init(nsIWidget* aParentWidget, // this is the owning reference. The nsCOMPtr will take care of releasing // our ref to the listener on destruction. NS_ADDREF(selectionListener); - rv = selectionListener->QueryInterface(NS_GET_IID(nsISelectionListener), getter_AddRefs(mSelectionListener)); + mSelectionListener = do_QueryInterface(selectionListener); NS_RELEASE(selectionListener); if (NS_FAILED(rv)) return rv; @@ -1060,7 +1024,7 @@ DocumentViewerImpl::Init(nsIWidget* aParentWidget, // this is the owning reference. The nsCOMPtr will take care of releasing // our ref to the listener on destruction. NS_ADDREF(focusListener); - rv = focusListener->QueryInterface(NS_GET_IID(nsIDOMFocusListener), getter_AddRefs(mFocusListener)); + mFocusListener = do_QueryInterface(focusListener); NS_RELEASE(focusListener); if (NS_FAILED(rv)) return rv; @@ -1068,8 +1032,7 @@ DocumentViewerImpl::Init(nsIWidget* aParentWidget, if(mDocument) { // get the DOM event receiver - nsCOMPtr erP; - rv = mDocument->QueryInterface(NS_GET_IID(nsIDOMEventReceiver), getter_AddRefs(erP)); + nsCOMPtr erP (do_QueryInterface(mDocument, &rv)); if(NS_FAILED(rv) || !erP) return rv?rv:NS_ERROR_FAILURE; @@ -1166,13 +1129,19 @@ DocumentViewerImpl::Unload() } NS_IMETHODIMP -DocumentViewerImpl::Destroy() +DocumentViewerImpl::Close() { - // All callers are supposed to call destroy to break circular + // All callers are supposed to call close to break circular // references. If we do this stuff in the destructor, the // destructor might never be called (especially if we're being // used from JS. + // Close is also needed to disable scripts during paint suppression, + // since we transfer the existing global object to the new document + // that is loaded. In the future, the global object may become a proxy + // for an object that can be switched in and out so that we don't need + // to disable scripts during paint suppression. + nsresult rv; if (mDocument) { @@ -1187,13 +1156,41 @@ DocumentViewerImpl::Destroy() mDocument->SetScriptGlobalObject(nsnull); if (mFocusListener) { // get the DOM event receiver - nsCOMPtr erP; - rv = mDocument->QueryInterface(NS_GET_IID(nsIDOMEventReceiver), getter_AddRefs(erP)); + nsCOMPtr erP( do_QueryInterface(mDocument, &rv) ); if(NS_SUCCEEDED(rv) && erP) erP->RemoveEventListenerByIID(mFocusListener, NS_GET_IID(nsIDOMFocusListener)); } } + mDocument = nsnull; + return NS_OK; +} + +NS_IMETHODIMP +DocumentViewerImpl::Destroy() +{ + // All callers are supposed to call destroy to break circular + // references. If we do this stuff in the destructor, the + // destructor might never be called (especially if we're being + // used from JS. + + if (mPagePrintTimer != nsnull) { + mPagePrintTimer->Stop(); + delete mPagePrintTimer; + } + + if (mPrt) { + mPrt->OnEndPrinting(NS_ERROR_FAILURE); + delete mPrt; + mPrt = nsnull; + } + + // Avoid leaking the old viewer. + if (mPreviousViewer) { + mPreviousViewer->Destroy(); + mPreviousViewer = nsnull; + } + if (mDeviceContext) mDeviceContext->FlushFontCache(); @@ -1201,13 +1198,14 @@ DocumentViewerImpl::Destroy() // Break circular reference (or something) mPresShell->EndObservingDocument(); nsCOMPtr selection; - rv = GetDocumentSelection(getter_AddRefs(selection)); + nsresult rv = GetDocumentSelection(getter_AddRefs(selection)); nsCOMPtr selPrivate(do_QueryInterface(selection)); if (NS_SUCCEEDED(rv) && selPrivate && mSelectionListener) selPrivate->RemoveSelectionListener(mSelectionListener); + mPresShell->Destroy(); + mPresShell = nsnull; } - mDocument = nsnull; return NS_OK; } @@ -1291,6 +1289,7 @@ DocumentViewerImpl::SetDOMDocument(nsIDOMDocument *aDocument) // 3) Replace the current pres shell with a new shell for the new document mPresShell->EndObservingDocument(); + mPresShell->Destroy(); mPresShell = nsnull; rv = newDoc->CreateShell(mPresContext, mViewManager, styleSet, @@ -1302,8 +1301,7 @@ DocumentViewerImpl::SetDOMDocument(nsIDOMDocument *aDocument) // 4) Register the focus listener on the new document if(mDocument) { - nsCOMPtr erP; - rv = mDocument->QueryInterface(NS_GET_IID(nsIDOMEventReceiver), getter_AddRefs(erP)); + nsCOMPtr erP = do_QueryInterface(mDocument, &rv); if(NS_FAILED(rv) || !erP) return rv ? rv : NS_ERROR_FAILURE; @@ -1370,17 +1368,13 @@ DocumentViewerImpl::GetPreviousViewer(nsIContentViewer** aViewer) NS_IMETHODIMP DocumentViewerImpl::SetPreviousViewer(nsIContentViewer* aViewer) { - if (!aViewer) { - // Clearing it out. - mPreviousViewer = nsnull; + // NOTE: |Show| sets |mPreviousViewer| to null without calling this + // function. + + if (aViewer) { + NS_ASSERTION(!mPreviousViewer, + "can't set previous viewer when there already is one"); - // Now we can show, but only if we aren't dead already (which - // can occasionally happen when one page moves to another during the onload - // handler.) - if (mDocument) - Show(); - } - else { // In a multiple chaining situation (which occurs when running a thrashing // test like i-bench or jrgm's tests with no delay), we can build up a // whole chain of viewers. In order to avoid this, we always set our previous @@ -1392,9 +1386,9 @@ DocumentViewerImpl::SetPreviousViewer(nsIContentViewer* aViewer) nsCOMPtr prevViewer; aViewer->GetPreviousViewer(getter_AddRefs(prevViewer)); if (prevViewer) { - SetPreviousViewer(prevViewer); - prevViewer->SetPreviousViewer(nsnull); - return NS_OK; + aViewer->SetPreviousViewer(nsnull); + aViewer->Destroy(); + return SetPreviousViewer(prevViewer); } } @@ -1432,6 +1426,17 @@ DocumentViewerImpl::Show(void) { NS_ENSURE_TRUE(mDocument, NS_ERROR_NOT_AVAILABLE); NS_PRECONDITION(mWindow, "null window"); + + // We don't need the previous viewer anymore since we're not + // displaying it. + if (mPreviousViewer) { + // This little dance *may* only be to keep + // PresShell::EndObservingDocument happy, but I'm not sure. + nsCOMPtr prevViewer(mPreviousViewer); + mPreviousViewer = nsnull; + prevViewer->Destroy(); + } + if (mWindow) { mWindow->Show(PR_TRUE); } @@ -1491,7 +1496,7 @@ GetPresShellFor(nsIDocShell* aDocShell) aDocShell->GetContentViewer(&cv); if (nsnull != cv) { nsIDocumentViewer* docv = nsnull; - cv->QueryInterface(NS_GET_IID(nsIDocumentViewer), (void**) &docv); + CallQueryInterface(cv, &docv); if (nsnull != docv) { nsIPresContext* cx; docv->GetPresContext(cx); @@ -1537,7 +1542,7 @@ static void DumpFrames(FILE* out, nsAutoString tmp; nsIFrameDebug* frameDebug; - if (NS_SUCCEEDED(child->QueryInterface(NS_GET_IID(nsIFrameDebug), (void**)&frameDebug))) { + if (NS_SUCCEEDED(CallQueryInterface(child, &frameDebug))) { frameDebug->GetFrameName(tmp); } fputs(tmp, out); @@ -1665,7 +1670,7 @@ static void DumpPrintObjectsList(nsVoidArray * aDocList, FILE* aFD = nsnull) po->mPresShell->GetRootFrame(&rootFrame); while (rootFrame != nsnull) { nsIPageSequenceFrame * sqf = nsnull; - if (NS_SUCCEEDED(rootFrame->QueryInterface(NS_GET_IID(nsIPageSequenceFrame), (void**)&sqf)) && sqf) { + if (NS_SUCCEEDED(CallQueryInterface(rootFrame, &sqf)) && sqf) { break; } rootFrame->FirstChild(po->mPresContext, nsnull, &rootFrame); @@ -1721,7 +1726,7 @@ static void DumpPrintObjectsTreeLayout(PrintObject * aPO, } if (fd) { nsIFrame* rootFrame = nsnull; - if (aPO->mPresShell != nsnull) { + if (aPO->mPresShell) { aPO->mPresShell->GetRootFrame(&rootFrame); } for (PRInt32 k=0;kQueryInterface(NS_GET_IID(nsIFrame), (void **)&seqFrame))) { + if (NS_FAILED(CallQueryInterface(aPageSeqFrame, &seqFrame))) { return NS_ERROR_FAILURE; } @@ -2268,7 +2273,7 @@ DocumentViewerImpl::PrintPage(nsIPresContext* aPresContext, // page num of it's parent doc curPageSeq->GetCurrentPageNum(&pageNum); nsIFrame* fr; - curPageSeq->QueryInterface(NS_GET_IID(nsIFrame), (void**)&fr); + CallQueryInterface(curPageSeq, &fr); if (fr == po->mSeqFrame && pageNum == po->mPageNum) { PRBool donePrintingSubDoc; @@ -2425,7 +2430,7 @@ void DocumentViewerImpl::CalcPageFrameLocation(nsIPresShell * aPresShell, // Keep a pointer to the Seq and Page frames nsIPageSequenceFrame * sqf = nsnull; if (parent != nsnull && - NS_SUCCEEDED(parent->QueryInterface(NS_GET_IID(nsIPageSequenceFrame), (void**)&sqf)) && sqf) { + NS_SUCCEEDED(CallQueryInterface(parent, &sqf)) && sqf) { pageFrame = temp; seqFrame = parent; } @@ -2482,7 +2487,7 @@ DocumentViewerImpl::MapSubDocFrameLocations(PrintObject* aPO) CalcPageFrameLocation(aPO->mParent->mPresShell, aPO); } - if (aPO->mPresShell != nsnull) { + if (aPO->mPresShell) { for (PRInt32 i=0;imKids.Count();i++) { MapSubDocFrameLocations((PrintObject*)aPO->mKids[i]); } @@ -2732,7 +2737,7 @@ DocumentViewerImpl::ReflowPrintObject(PrintObject * aPO) if (NS_FAILED(rv)) { return rv; } else { - rv = printcon->QueryInterface(NS_GET_IID(nsIPresContext), (void**)&aPO->mPresContext); + aPO->mPresContext = do_QueryInterface(printcon); if (NS_FAILED(rv)) { return rv; } @@ -2741,16 +2746,14 @@ DocumentViewerImpl::ReflowPrintObject(PrintObject * aPO) // init it with the DC (aPO->mPresContext)->Init(mPrt->mPrintDocDC); - CreateStyleSet(document, &aPO->mStyleSet); + CreateStyleSet(document, getter_AddRefs(aPO->mStyleSet)); - rv = nsComponentManager::CreateInstance(kPresShellCID,nsnull, - NS_GET_IID(nsIPresShell),(void **)&aPO->mPresShell); + aPO->mPresShell = do_CreateInstance(kPresShellCID, &rv); if (NS_FAILED(rv)) { return rv; } - rv = nsComponentManager::CreateInstance(kViewManagerCID,nsnull, - NS_GET_IID(nsIViewManager),(void **)&aPO->mViewManager); + aPO->mViewManager = do_CreateInstance(kViewManagerCID, &rv); if (NS_FAILED(rv)) { return rv; } @@ -2796,7 +2799,7 @@ DocumentViewerImpl::ReflowPrintObject(PrintObject * aPO) nsRect tbounds = nsRect(0, 0, width, height); // Create a child window of the parent that is our "root view/window" - rv = nsComponentManager::CreateInstance(kViewCID, nsnull, NS_GET_IID(nsIView), (void **)&(aPO->mRootView)); + rv = CallCreateInstance(kViewCID, &aPO->mRootView); if (NS_FAILED(rv)) { return rv; } @@ -2807,7 +2810,8 @@ DocumentViewerImpl::ReflowPrintObject(PrintObject * aPO) // Setup hierarchical relationship in view manager aPO->mViewManager->SetRootView(aPO->mRootView); - aPO->mPresShell->Init(document, aPO->mPresContext, aPO->mViewManager,aPO->mStyleSet); + aPO->mPresShell->Init(document, aPO->mPresContext, + aPO->mViewManager, aPO->mStyleSet); nsCompatibility mode; mPresContext->GetCompatibilityMode(&mode); @@ -3435,7 +3439,7 @@ DocumentViewerImpl::DoPrint(PrintObject * aPO, PRBool aDoSyncPrinting, PRBool& a nsIFrame* root; poPresShell->GetRootFrame(&root); - if (NS_SUCCEEDED(root->QueryInterface(NS_GET_IID(nsIFrameDebug), (void**) &fdbg))) { + if (NS_SUCCEEDED(CallQueryInterface(root, &fdbg))) { fdbg->DumpRegressionData(poPresContext, mPrt->mFilePointer, 0, PR_TRUE); } fclose(mPrt->mFilePointer); @@ -3501,7 +3505,7 @@ DocumentViewerImpl::DoPrint(PrintObject * aPO, PRBool aDoSyncPrinting, PRBool& a if (startPageNum == endPageNum) { nsIFrame * seqFrame; - if (NS_FAILED(pageSequence->QueryInterface(NS_GET_IID(nsIFrame), (void **)&seqFrame))) { + if (NS_FAILED(CallQueryInterface(pageSequence, &seqFrame))) { gCurrentlyPrinting = PR_FALSE; return NS_ERROR_FAILURE; } @@ -3518,7 +3522,7 @@ DocumentViewerImpl::DoPrint(PrintObject * aPO, PRBool aDoSyncPrinting, PRBool& a } nsIFrame * seqFrame; - if (NS_FAILED(pageSequence->QueryInterface(NS_GET_IID(nsIFrame), (void **)&seqFrame))) { + if (NS_FAILED(CallQueryInterface(pageSequence, &seqFrame))) { gCurrentlyPrinting = PR_FALSE; return NS_ERROR_FAILURE; } @@ -3582,11 +3586,13 @@ DocumentViewerImpl::CalcNumPrintableDocsAndPages(PRInt32& aNumDocs, PRInt32& aNu PrintObject* po = (PrintObject*)mPrt->mPrintDocList->ElementAt(i); NS_ASSERTION(po, "PrintObject can't be null!"); if (po->IsPrintable()) { - if (po->mPresShell != nsnull && (po->mFrameType != eIFrame && po->mFrameType != eFrameSet)) { + if (po->mPresShell && + po->mFrameType != eIFrame && + po->mFrameType != eFrameSet) { nsIPageSequenceFrame* pageSequence; po->mPresShell->GetPageSequenceFrame(&pageSequence); nsIFrame * seqFrame; - if (NS_SUCCEEDED(pageSequence->QueryInterface(NS_GET_IID(nsIFrame), (void **)&seqFrame))) { + if (NS_SUCCEEDED(CallQueryInterface(pageSequence, &seqFrame))) { nsIFrame* frame; seqFrame->FirstChild(po->mPresContext, nsnull, &frame); while (frame) { @@ -3765,7 +3771,7 @@ DocumentViewerImpl::CreateStyleSet(nsIDocument* aDocument, NS_WARNING("unable to load UA style sheet"); } - rv = nsComponentManager::CreateInstance(kStyleSetCID,nsnull,NS_GET_IID(nsIStyleSet),(void**)aStyleSet); + rv = CallCreateInstance(kStyleSetCID, aStyleSet); if (NS_OK == rv) { PRInt32 index = 0; aDocument->GetNumberOfStyleSheets(&index); @@ -3838,10 +3844,9 @@ DocumentViewerImpl::MakeWindow(nsIWidget* aParentWidget, { nsresult rv; - rv = nsComponentManager::CreateInstance(kViewManagerCID, - nsnull, - NS_GET_IID(nsIViewManager), - getter_AddRefs(mViewManager)); + mViewManager = do_CreateInstance(kViewManagerCID, &rv); + if (NS_FAILED(rv)) + return rv; nsCOMPtr dx; mPresContext->GetDeviceContext(getter_AddRefs(dx)); @@ -3852,11 +3857,12 @@ DocumentViewerImpl::MakeWindow(nsIWidget* aParentWidget, mPresContext->GetPixelsToTwips(&p2t); tbounds *= p2t; - // Initialize the view manager with an offset. This allows the viewmanager - // to manage a coordinate space offset from (0,0) - if ((NS_OK != rv) || (NS_OK != mViewManager->Init(dx, tbounds.x, tbounds.y))) { + // Initialize the view manager with an offset. This allows the viewmanager + // to manage a coordinate space offset from (0,0) + rv = mViewManager->Init(dx, tbounds.x, tbounds.y); + if (NS_FAILED(rv)) return rv; - } + // Reset the bounds offset so the root view is set to 0,0. The offset is // specified in nsIViewManager::Init above. // Besides, layout will reset the root view to (0,0) during reflow, @@ -3867,15 +3873,12 @@ DocumentViewerImpl::MakeWindow(nsIWidget* aParentWidget, // Create a child window of the parent that is our "root view/window" // Create a view - rv = nsComponentManager::CreateInstance(kViewCID, - nsnull, - NS_GET_IID(nsIView), - (void**)&mView); - if ((NS_OK != rv) || (NS_OK != mView->Init(mViewManager, - tbounds, - nsnull))) { + rv = CallCreateInstance(kViewCID, &mView); + if (NS_FAILED(rv)) + return rv; + rv = mView->Init(mViewManager, tbounds, nsnull); + if (NS_FAILED(rv)) return rv; - } rv = mView->CreateWidget(kWidgetCID, nsnull, aParentWidget->GetNativeData(NS_NATIVE_WIDGET)); @@ -4064,10 +4067,7 @@ NS_IMETHODIMP DocumentViewerImpl::SelectAll() if (NS_FAILED(rv)) return rv; static NS_DEFINE_CID(kCDOMRangeCID, NS_RANGE_CID); - nsCOMPtr range; - rv = nsComponentManager::CreateInstance(kCDOMRangeCID, nsnull, - NS_GET_IID(nsIDOMRange), - getter_AddRefs(range)); + nsCOMPtr range = do_CreateInstance(kCDOMRangeCID, &rv); rv = range->SelectNodeContents(bodyNode); if (NS_FAILED(rv)) return rv; @@ -4320,10 +4320,7 @@ nsresult rv; // another is still in here (the printing dialog is a good example). if(gCurrentlyPrinting) { // Beep at the user, let them know we are not ready to print. - nsCOMPtr soundInterface; - rv = nsComponentManager::CreateInstance(kSoundCID, - nsnull, NS_GET_IID(nsISound), - getter_AddRefs(soundInterface)); + nsCOMPtr soundInterface( do_CreateInstance(kSoundCID, &rv) ); if (NS_SUCCEEDED(rv) && (soundInterface != nsnull)){ soundInterface->Beep(); } @@ -4425,11 +4422,8 @@ nsresult rv; } #endif - nsCOMPtr factory; - nsComponentManager::CreateInstance(kDeviceContextSpecFactoryCID, - nsnull, - NS_GET_IID(nsIDeviceContextSpecFactory), - (void **)getter_AddRefs(factory)); + nsCOMPtr factory = + do_CreateInstance(kDeviceContextSpecFactoryCID); if (factory) { @@ -4439,13 +4433,13 @@ nsresult rv; nsIDeviceContextSpec *devspec = nsnull; nsCOMPtr dx; - mPrt->mPrintDC = nsnull; + mPrt->mPrintDC = nsnull; // XXX why? mPrt->mFilePointer = aFile; factory->CreateDeviceContextSpec(mWindow, devspec, aSilent); if (nsnull != devspec) { mPresContext->GetDeviceContext(getter_AddRefs(dx)); - rv = dx->GetDeviceContextFor(devspec, mPrt->mPrintDC); + rv = dx->GetDeviceContextFor(devspec, *getter_AddRefs(mPrt->mPrintDC)); if (NS_SUCCEEDED(rv)) { NS_RELEASE(devspec); @@ -4457,7 +4451,7 @@ nsresult rv; gCurrentlyPrinting = PR_FALSE; return rv; } else { - rv = printcon->QueryInterface(NS_GET_IID(nsIPresContext), (void**)&mPrt->mPrintPC); + mPrt->mPrintPC = do_QueryInterface(printcon, &rv); if (NS_FAILED(rv)) { gCurrentlyPrinting = PR_FALSE; return rv; @@ -4478,15 +4472,15 @@ nsresult rv; mPrt->mPrintPC->Init(mPrt->mPrintDC); mPrt->mPrintPC->SetContainer(webContainer); - CreateStyleSet(mDocument,&mPrt->mPrintSS); + CreateStyleSet(mDocument, getter_AddRefs(mPrt->mPrintSS)); - rv = nsComponentManager::CreateInstance(kPresShellCID, nsnull, NS_GET_IID(nsIPresShell),(void**)&mPrt->mPrintPS); + mPrt->mPrintPS = do_CreateInstance(kPresShellCID, &rv); if(NS_FAILED(rv)){ gCurrentlyPrinting = PR_FALSE; return rv; } - rv = nsComponentManager::CreateInstance(kViewManagerCID, nsnull, NS_GET_IID(nsIViewManager),(void**)&mPrt->mPrintVM); + mPrt->mPrintVM = do_CreateInstance(kViewManagerCID, &rv); if(NS_FAILED(rv)) { gCurrentlyPrinting = PR_FALSE; return rv; @@ -4498,7 +4492,7 @@ nsresult rv; return rv; } - rv = nsComponentManager::CreateInstance(kViewCID, nsnull, NS_GET_IID(nsIView),(void**)&mPrt->mPrintView); + rv = CallCreateInstance(kViewCID, &mPrt->mPrintView); if(NS_FAILED(rv)) { gCurrentlyPrinting = PR_FALSE; return rv; @@ -5146,7 +5140,7 @@ NS_IMETHODIMP DocumentViewerImpl::SizeToContent() #pragma mark - #endif -NS_IMPL_ISUPPORTS(nsDocViewerSelectionListener, NS_GET_IID(nsISelectionListener)); +NS_IMPL_ISUPPORTS1(nsDocViewerSelectionListener, nsISelectionListener); nsresult nsDocViewerSelectionListener::Init(DocumentViewerImpl *aDocViewer) { @@ -5368,7 +5362,7 @@ NS_IMETHODIMP nsDocViewerSelectionListener::NotifySelectionChanged(nsIDOMDocumen } //nsDocViewerFocusListener -NS_IMPL_ISUPPORTS(nsDocViewerFocusListener, NS_GET_IID(nsIDOMFocusListener)); +NS_IMPL_ISUPPORTS1(nsDocViewerFocusListener, nsIDOMFocusListener); nsDocViewerFocusListener::nsDocViewerFocusListener() :mDocViewer(nsnull) diff --git a/mozilla/layout/base/nsIPresShell.h b/mozilla/layout/base/nsIPresShell.h index 34035caad1f..61b91b030d4 100644 --- a/mozilla/layout/base/nsIPresShell.h +++ b/mozilla/layout/base/nsIPresShell.h @@ -125,6 +125,15 @@ public: nsIViewManager* aViewManager, nsIStyleSet* aStyleSet) = 0; + /** + * All callers are responsible for calling |Destroy| after calling + * |EndObservingDocument|. It needs to be separate only because form + * controls incorrectly store their data in the frames rather than the + * content model and printing calls |EndObservingDocument| multiple + * times to make form controls behave nicely when printed. + */ + NS_IMETHOD Destroy() = 0; + // All frames owned by the shell are allocated from an arena. They are also recycled // using free lists (separate free lists being maintained for each size_t). // Methods for recycling frames. diff --git a/mozilla/layout/base/nsPresShell.cpp b/mozilla/layout/base/nsPresShell.cpp index 7fa3ba333fa..dc85987a70e 100644 --- a/mozilla/layout/base/nsPresShell.cpp +++ b/mozilla/layout/base/nsPresShell.cpp @@ -807,6 +807,7 @@ public: nsIPresContext* aPresContext, nsIViewManager* aViewManager, nsIStyleSet* aStyleSet); + NS_IMETHOD Destroy(); NS_IMETHOD AllocateFrame(size_t aSize, void** aResult); NS_IMETHOD FreeFrame(size_t aSize, void* aFreeChunk); @@ -1482,111 +1483,20 @@ PresShell::QueryInterface(const nsIID& aIID, void** aInstancePtr) PresShell::~PresShell() { -#ifdef MOZ_REFLOW_PERF - DumpReflows(); - if (mReflowCountMgr) { - delete mReflowCountMgr; - mReflowCountMgr = nsnull; + if (mStyleSet) { + NS_NOTREACHED("Someone did not call nsIPresShell::destroy"); + Destroy(); } -#endif - - // If our paint suppression timer is still active, kill it. - if (mPaintSuppressionTimer) { - mPaintSuppressionTimer->Cancel(); - mPaintSuppressionTimer = nsnull; - } - - nsCOMPtr container; - mPresContext->GetContainer(getter_AddRefs(container)); - if (container) { - nsCOMPtr cvc(do_QueryInterface(container)); - if (cvc) { - nsCOMPtr cv; - cvc->GetContentViewer(getter_AddRefs(cv)); - if (cv) - cv->SetPreviousViewer(nsnull); - } - } - - // release our pref style sheet, if we have one still - ClearPreferenceStyleRules(); // if we allocated any stack memory free it. FreeDynamicStack(); - - // free our table of anonymous content - ReleaseAnonymousContent(); - - mIsDestroying = PR_TRUE; - - // Clobber weak leaks in case of re-entrancy during tear down - mHistoryState = nsnull; - - // kill subshell map, if any. It holds only weak references - if (mSubShellMap) - { - delete mSubShellMap; - mSubShellMap = nsnull; - } - - // release current event content and any content on event stack - NS_IF_RELEASE(mCurrentEventContent); - - PRInt32 i, count = mCurrentEventContentStack.Count(); - nsIContent* currentEventContent; - for (i = 0; i < count; i++) { - currentEventContent = (nsIContent*)mCurrentEventContentStack.ElementAt(i); - NS_IF_RELEASE(currentEventContent); - } - - if (mViewManager) { - // Disable paints during tear down of the frame tree - mViewManager->DisableRefresh(); - mViewManager = nsnull; - } - - // This shell must be removed from the document before the frame - // hierarchy is torn down to avoid finding deleted frames through - // this presshell while the frames are being torn down - if (mDocument) { - mDocument->DeleteShell(this); - } - - // Destroy the frame manager. This will destroy the frame hierarchy - if (mFrameManager) { - mFrameManager->Destroy(); - NS_RELEASE(mFrameManager); - } - - // Let the style set do its cleanup. - mStyleSet->Shutdown(); - - // We hold a reference to the pres context, and it holds a weak link back - // to us. To avoid the pres context having a dangling reference, set its - // pres shell to NULL - if (mPresContext) { - mPresContext->SetShell(nsnull); - } - - if (mViewEventListener) { - mViewEventListener->SetPresShell((nsIPresShell*)nsnull); - NS_RELEASE(mViewEventListener); - } - - // Revoke pending reflow events - if (mPendingReflowEvent) { - mPendingReflowEvent = PR_FALSE; - mEventQueue->RevokeEvents(this); - } - - KillResizeEventTimer(); } /** * Initialize the presentation shell. Create view manager and style * manager. */ -nsresult +NS_IMETHODIMP PresShell::Init(nsIDocument* aDocument, nsIPresContext* aPresContext, nsIViewManager* aViewManager, @@ -1614,7 +1524,7 @@ PresShell::Init(nsIDocument* aDocument, mPresContext = dont_QueryInterface(aPresContext); aPresContext->SetShell(this); - mStyleSet = dont_QueryInterface(aStyleSet); + mStyleSet = aStyleSet; mHistoryState = nsnull; @@ -1719,6 +1629,116 @@ PresShell::Init(nsIDocument* aDocument, } #endif + return NS_OK; +} + +NS_IMETHODIMP +PresShell::Destroy() +{ +#ifdef MOZ_REFLOW_PERF + DumpReflows(); + if (mReflowCountMgr) { + delete mReflowCountMgr; + mReflowCountMgr = nsnull; + } +#endif + + // If our paint suppression timer is still active, kill it. + if (mPaintSuppressionTimer) { + mPaintSuppressionTimer->Cancel(); + mPaintSuppressionTimer = nsnull; + } + +#ifdef DEBUG + { + nsCOMPtr container; + mPresContext->GetContainer(getter_AddRefs(container)); + if (container) { + nsCOMPtr cvc(do_QueryInterface(container)); + if (cvc) { + nsCOMPtr cv; + cvc->GetContentViewer(getter_AddRefs(cv)); + if (cv) { + nsCOMPtr prevViewer; + cv->GetPreviousViewer(getter_AddRefs(prevViewer)); + NS_ASSERTION(!prevViewer, "still have a previous viewer!"); + } + } + } + } +#endif + + // release our pref style sheet, if we have one still + ClearPreferenceStyleRules(); + + // free our table of anonymous content + ReleaseAnonymousContent(); + + mIsDestroying = PR_TRUE; + + // Clobber weak leaks in case of re-entrancy during tear down + mHistoryState = nsnull; + + // kill subshell map, if any. It holds only weak references + if (mSubShellMap) + { + delete mSubShellMap; + mSubShellMap = nsnull; + } + + // release current event content and any content on event stack + NS_IF_RELEASE(mCurrentEventContent); + + PRInt32 i, count = mCurrentEventContentStack.Count(); + nsIContent* currentEventContent; + for (i = 0; i < count; i++) { + currentEventContent = (nsIContent*)mCurrentEventContentStack.ElementAt(i); + NS_IF_RELEASE(currentEventContent); + } + + if (mViewManager) { + // Disable paints during tear down of the frame tree + mViewManager->DisableRefresh(); + mViewManager = nsnull; + } + + // This shell must be removed from the document before the frame + // hierarchy is torn down to avoid finding deleted frames through + // this presshell while the frames are being torn down + if (mDocument) { + mDocument->DeleteShell(this); + } + + // Destroy the frame manager. This will destroy the frame hierarchy + if (mFrameManager) { + mFrameManager->Destroy(); + NS_RELEASE(mFrameManager); + } + + // Let the style set do its cleanup. + mStyleSet->Shutdown(); + mStyleSet = nsnull; + + // We hold a reference to the pres context, and it holds a weak link back + // to us. To avoid the pres context having a dangling reference, set its + // pres shell to NULL + if (mPresContext) { + mPresContext->SetShell(nsnull); + } + + if (mViewEventListener) { + mViewEventListener->SetPresShell((nsIPresShell*)nsnull); + NS_RELEASE(mViewEventListener); + } + + // Revoke pending reflow events + if (mPendingReflowEvent) { + mPendingReflowEvent = PR_FALSE; + mEventQueue->RevokeEvents(this); + } + + KillResizeEventTimer(); + return NS_OK; } @@ -2447,6 +2467,7 @@ PresShell::EndObservingDocument() return NS_ERROR_UNEXPECTED; mSelection->ShutDown(); } + return NS_OK; } @@ -4579,23 +4600,17 @@ PresShell::UnsuppressAndInvalidate() focusController->SetSuppressFocus(PR_TRUE, "PresShell suppression on Web page loads"); nsCOMPtr container; - nsCOMPtr cv; - nsCOMPtr dv; mPresContext->GetContainer(getter_AddRefs(container)); if (container) { nsCOMPtr cvc(do_QueryInterface(container)); if (cvc) { + nsCOMPtr cv; cvc->GetContentViewer(getter_AddRefs(cv)); - dv = do_QueryInterface(cv); + if (cv) + cv->Show(); } } - if (dv) - dv->Show(); - - if (cv) - cv->SetPreviousViewer(nsnull); - mPaintingSuppressed = PR_FALSE; nsIFrame* rootFrame; mFrameManager->GetRootFrame(&rootFrame); diff --git a/mozilla/layout/base/public/nsIPresShell.h b/mozilla/layout/base/public/nsIPresShell.h index 34035caad1f..61b91b030d4 100644 --- a/mozilla/layout/base/public/nsIPresShell.h +++ b/mozilla/layout/base/public/nsIPresShell.h @@ -125,6 +125,15 @@ public: nsIViewManager* aViewManager, nsIStyleSet* aStyleSet) = 0; + /** + * All callers are responsible for calling |Destroy| after calling + * |EndObservingDocument|. It needs to be separate only because form + * controls incorrectly store their data in the frames rather than the + * content model and printing calls |EndObservingDocument| multiple + * times to make form controls behave nicely when printed. + */ + NS_IMETHOD Destroy() = 0; + // All frames owned by the shell are allocated from an arena. They are also recycled // using free lists (separate free lists being maintained for each size_t). // Methods for recycling frames. diff --git a/mozilla/layout/generic/nsObjectFrame.cpp b/mozilla/layout/generic/nsObjectFrame.cpp index 10c0d52b6cd..3ce4aab8f7a 100644 --- a/mozilla/layout/generic/nsObjectFrame.cpp +++ b/mozilla/layout/generic/nsObjectFrame.cpp @@ -440,7 +440,7 @@ nsObjectFrame::Init(nsIPresContext* aPresContext, nsCOMPtr cv; cvc->GetContentViewer(getter_AddRefs(cv)); if (cv) - cv->SetPreviousViewer(nsnull); + cv->Show(); } } diff --git a/mozilla/layout/html/base/src/nsObjectFrame.cpp b/mozilla/layout/html/base/src/nsObjectFrame.cpp index 10c0d52b6cd..3ce4aab8f7a 100644 --- a/mozilla/layout/html/base/src/nsObjectFrame.cpp +++ b/mozilla/layout/html/base/src/nsObjectFrame.cpp @@ -440,7 +440,7 @@ nsObjectFrame::Init(nsIPresContext* aPresContext, nsCOMPtr cv; cvc->GetContentViewer(getter_AddRefs(cv)); if (cv) - cv->SetPreviousViewer(nsnull); + cv->Show(); } } diff --git a/mozilla/layout/html/base/src/nsPresShell.cpp b/mozilla/layout/html/base/src/nsPresShell.cpp index 7fa3ba333fa..dc85987a70e 100644 --- a/mozilla/layout/html/base/src/nsPresShell.cpp +++ b/mozilla/layout/html/base/src/nsPresShell.cpp @@ -807,6 +807,7 @@ public: nsIPresContext* aPresContext, nsIViewManager* aViewManager, nsIStyleSet* aStyleSet); + NS_IMETHOD Destroy(); NS_IMETHOD AllocateFrame(size_t aSize, void** aResult); NS_IMETHOD FreeFrame(size_t aSize, void* aFreeChunk); @@ -1482,111 +1483,20 @@ PresShell::QueryInterface(const nsIID& aIID, void** aInstancePtr) PresShell::~PresShell() { -#ifdef MOZ_REFLOW_PERF - DumpReflows(); - if (mReflowCountMgr) { - delete mReflowCountMgr; - mReflowCountMgr = nsnull; + if (mStyleSet) { + NS_NOTREACHED("Someone did not call nsIPresShell::destroy"); + Destroy(); } -#endif - - // If our paint suppression timer is still active, kill it. - if (mPaintSuppressionTimer) { - mPaintSuppressionTimer->Cancel(); - mPaintSuppressionTimer = nsnull; - } - - nsCOMPtr container; - mPresContext->GetContainer(getter_AddRefs(container)); - if (container) { - nsCOMPtr cvc(do_QueryInterface(container)); - if (cvc) { - nsCOMPtr cv; - cvc->GetContentViewer(getter_AddRefs(cv)); - if (cv) - cv->SetPreviousViewer(nsnull); - } - } - - // release our pref style sheet, if we have one still - ClearPreferenceStyleRules(); // if we allocated any stack memory free it. FreeDynamicStack(); - - // free our table of anonymous content - ReleaseAnonymousContent(); - - mIsDestroying = PR_TRUE; - - // Clobber weak leaks in case of re-entrancy during tear down - mHistoryState = nsnull; - - // kill subshell map, if any. It holds only weak references - if (mSubShellMap) - { - delete mSubShellMap; - mSubShellMap = nsnull; - } - - // release current event content and any content on event stack - NS_IF_RELEASE(mCurrentEventContent); - - PRInt32 i, count = mCurrentEventContentStack.Count(); - nsIContent* currentEventContent; - for (i = 0; i < count; i++) { - currentEventContent = (nsIContent*)mCurrentEventContentStack.ElementAt(i); - NS_IF_RELEASE(currentEventContent); - } - - if (mViewManager) { - // Disable paints during tear down of the frame tree - mViewManager->DisableRefresh(); - mViewManager = nsnull; - } - - // This shell must be removed from the document before the frame - // hierarchy is torn down to avoid finding deleted frames through - // this presshell while the frames are being torn down - if (mDocument) { - mDocument->DeleteShell(this); - } - - // Destroy the frame manager. This will destroy the frame hierarchy - if (mFrameManager) { - mFrameManager->Destroy(); - NS_RELEASE(mFrameManager); - } - - // Let the style set do its cleanup. - mStyleSet->Shutdown(); - - // We hold a reference to the pres context, and it holds a weak link back - // to us. To avoid the pres context having a dangling reference, set its - // pres shell to NULL - if (mPresContext) { - mPresContext->SetShell(nsnull); - } - - if (mViewEventListener) { - mViewEventListener->SetPresShell((nsIPresShell*)nsnull); - NS_RELEASE(mViewEventListener); - } - - // Revoke pending reflow events - if (mPendingReflowEvent) { - mPendingReflowEvent = PR_FALSE; - mEventQueue->RevokeEvents(this); - } - - KillResizeEventTimer(); } /** * Initialize the presentation shell. Create view manager and style * manager. */ -nsresult +NS_IMETHODIMP PresShell::Init(nsIDocument* aDocument, nsIPresContext* aPresContext, nsIViewManager* aViewManager, @@ -1614,7 +1524,7 @@ PresShell::Init(nsIDocument* aDocument, mPresContext = dont_QueryInterface(aPresContext); aPresContext->SetShell(this); - mStyleSet = dont_QueryInterface(aStyleSet); + mStyleSet = aStyleSet; mHistoryState = nsnull; @@ -1719,6 +1629,116 @@ PresShell::Init(nsIDocument* aDocument, } #endif + return NS_OK; +} + +NS_IMETHODIMP +PresShell::Destroy() +{ +#ifdef MOZ_REFLOW_PERF + DumpReflows(); + if (mReflowCountMgr) { + delete mReflowCountMgr; + mReflowCountMgr = nsnull; + } +#endif + + // If our paint suppression timer is still active, kill it. + if (mPaintSuppressionTimer) { + mPaintSuppressionTimer->Cancel(); + mPaintSuppressionTimer = nsnull; + } + +#ifdef DEBUG + { + nsCOMPtr container; + mPresContext->GetContainer(getter_AddRefs(container)); + if (container) { + nsCOMPtr cvc(do_QueryInterface(container)); + if (cvc) { + nsCOMPtr cv; + cvc->GetContentViewer(getter_AddRefs(cv)); + if (cv) { + nsCOMPtr prevViewer; + cv->GetPreviousViewer(getter_AddRefs(prevViewer)); + NS_ASSERTION(!prevViewer, "still have a previous viewer!"); + } + } + } + } +#endif + + // release our pref style sheet, if we have one still + ClearPreferenceStyleRules(); + + // free our table of anonymous content + ReleaseAnonymousContent(); + + mIsDestroying = PR_TRUE; + + // Clobber weak leaks in case of re-entrancy during tear down + mHistoryState = nsnull; + + // kill subshell map, if any. It holds only weak references + if (mSubShellMap) + { + delete mSubShellMap; + mSubShellMap = nsnull; + } + + // release current event content and any content on event stack + NS_IF_RELEASE(mCurrentEventContent); + + PRInt32 i, count = mCurrentEventContentStack.Count(); + nsIContent* currentEventContent; + for (i = 0; i < count; i++) { + currentEventContent = (nsIContent*)mCurrentEventContentStack.ElementAt(i); + NS_IF_RELEASE(currentEventContent); + } + + if (mViewManager) { + // Disable paints during tear down of the frame tree + mViewManager->DisableRefresh(); + mViewManager = nsnull; + } + + // This shell must be removed from the document before the frame + // hierarchy is torn down to avoid finding deleted frames through + // this presshell while the frames are being torn down + if (mDocument) { + mDocument->DeleteShell(this); + } + + // Destroy the frame manager. This will destroy the frame hierarchy + if (mFrameManager) { + mFrameManager->Destroy(); + NS_RELEASE(mFrameManager); + } + + // Let the style set do its cleanup. + mStyleSet->Shutdown(); + mStyleSet = nsnull; + + // We hold a reference to the pres context, and it holds a weak link back + // to us. To avoid the pres context having a dangling reference, set its + // pres shell to NULL + if (mPresContext) { + mPresContext->SetShell(nsnull); + } + + if (mViewEventListener) { + mViewEventListener->SetPresShell((nsIPresShell*)nsnull); + NS_RELEASE(mViewEventListener); + } + + // Revoke pending reflow events + if (mPendingReflowEvent) { + mPendingReflowEvent = PR_FALSE; + mEventQueue->RevokeEvents(this); + } + + KillResizeEventTimer(); + return NS_OK; } @@ -2447,6 +2467,7 @@ PresShell::EndObservingDocument() return NS_ERROR_UNEXPECTED; mSelection->ShutDown(); } + return NS_OK; } @@ -4579,23 +4600,17 @@ PresShell::UnsuppressAndInvalidate() focusController->SetSuppressFocus(PR_TRUE, "PresShell suppression on Web page loads"); nsCOMPtr container; - nsCOMPtr cv; - nsCOMPtr dv; mPresContext->GetContainer(getter_AddRefs(container)); if (container) { nsCOMPtr cvc(do_QueryInterface(container)); if (cvc) { + nsCOMPtr cv; cvc->GetContentViewer(getter_AddRefs(cv)); - dv = do_QueryInterface(cv); + if (cv) + cv->Show(); } } - if (dv) - dv->Show(); - - if (cv) - cv->SetPreviousViewer(nsnull); - mPaintingSuppressed = PR_FALSE; nsIFrame* rootFrame; mFrameManager->GetRootFrame(&rootFrame); diff --git a/mozilla/modules/plugin/base/src/nsPluginViewer.cpp b/mozilla/modules/plugin/base/src/nsPluginViewer.cpp index c0f908419a8..6873cbe5de1 100644 --- a/mozilla/modules/plugin/base/src/nsPluginViewer.cpp +++ b/mozilla/modules/plugin/base/src/nsPluginViewer.cpp @@ -169,28 +169,7 @@ public: NS_IMETHOD StartLoad(nsIRequest* request, nsIStreamListener*& aResult); // nsIContentViewer - NS_IMETHOD Init(nsIWidget* aParentWidget, - nsIDeviceContext* aDeviceContext, - const nsRect& aBounds); - NS_IMETHOD SetContainer(nsISupports* aContainer); - NS_IMETHOD GetContainer(nsISupports** aContainerResult); - NS_IMETHOD LoadStart(nsISupports* aDoc); - NS_IMETHOD LoadComplete(nsresult aStatus); - NS_IMETHOD Unload(void); - NS_IMETHOD Destroy(void); - NS_IMETHOD Stop(void); - NS_IMETHOD GetDOMDocument(nsIDOMDocument **aResult); - NS_IMETHOD SetDOMDocument(nsIDOMDocument *aDocument); - NS_IMETHOD GetBounds(nsRect& aResult); - NS_IMETHOD SetBounds(const nsRect& aBounds); - NS_IMETHOD GetPreviousViewer(nsIContentViewer** aViewer); - NS_IMETHOD SetPreviousViewer(nsIContentViewer* aViewer); - NS_IMETHOD Move(PRInt32 aX, PRInt32 aY); - NS_IMETHOD Show(); - NS_IMETHOD Hide(); - NS_IMETHOD Validate(); - NS_IMETHOD SetEnableRendering(PRBool aOn); - NS_IMETHOD GetEnableRendering(PRBool* aResult); + NS_DECL_NSICONTENTVIEWER // nsIContentViewerEdit NS_DECL_NSICONTENTVIEWEREDIT @@ -435,6 +414,12 @@ PluginViewerImpl::Unload(void) return NS_OK; } +NS_IMETHODIMP +PluginViewerImpl::Close(void) +{ + return NS_OK; +} + NS_IMETHODIMP PluginViewerImpl::Destroy(void) { @@ -558,6 +543,8 @@ PluginViewerImpl::GetPreviousViewer(nsIContentViewer** aViewer) NS_IMETHODIMP PluginViewerImpl::SetPreviousViewer(nsIContentViewer* aViewer) { + if (aViewer) + aViewer->Destroy(); return NS_OK; } diff --git a/mozilla/modules/plugin/nglsrc/nsPluginViewer.cpp b/mozilla/modules/plugin/nglsrc/nsPluginViewer.cpp index c0f908419a8..6873cbe5de1 100644 --- a/mozilla/modules/plugin/nglsrc/nsPluginViewer.cpp +++ b/mozilla/modules/plugin/nglsrc/nsPluginViewer.cpp @@ -169,28 +169,7 @@ public: NS_IMETHOD StartLoad(nsIRequest* request, nsIStreamListener*& aResult); // nsIContentViewer - NS_IMETHOD Init(nsIWidget* aParentWidget, - nsIDeviceContext* aDeviceContext, - const nsRect& aBounds); - NS_IMETHOD SetContainer(nsISupports* aContainer); - NS_IMETHOD GetContainer(nsISupports** aContainerResult); - NS_IMETHOD LoadStart(nsISupports* aDoc); - NS_IMETHOD LoadComplete(nsresult aStatus); - NS_IMETHOD Unload(void); - NS_IMETHOD Destroy(void); - NS_IMETHOD Stop(void); - NS_IMETHOD GetDOMDocument(nsIDOMDocument **aResult); - NS_IMETHOD SetDOMDocument(nsIDOMDocument *aDocument); - NS_IMETHOD GetBounds(nsRect& aResult); - NS_IMETHOD SetBounds(const nsRect& aBounds); - NS_IMETHOD GetPreviousViewer(nsIContentViewer** aViewer); - NS_IMETHOD SetPreviousViewer(nsIContentViewer* aViewer); - NS_IMETHOD Move(PRInt32 aX, PRInt32 aY); - NS_IMETHOD Show(); - NS_IMETHOD Hide(); - NS_IMETHOD Validate(); - NS_IMETHOD SetEnableRendering(PRBool aOn); - NS_IMETHOD GetEnableRendering(PRBool* aResult); + NS_DECL_NSICONTENTVIEWER // nsIContentViewerEdit NS_DECL_NSICONTENTVIEWEREDIT @@ -435,6 +414,12 @@ PluginViewerImpl::Unload(void) return NS_OK; } +NS_IMETHODIMP +PluginViewerImpl::Close(void) +{ + return NS_OK; +} + NS_IMETHODIMP PluginViewerImpl::Destroy(void) { @@ -558,6 +543,8 @@ PluginViewerImpl::GetPreviousViewer(nsIContentViewer** aViewer) NS_IMETHODIMP PluginViewerImpl::SetPreviousViewer(nsIContentViewer* aViewer) { + if (aViewer) + aViewer->Destroy(); return NS_OK; }