зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1289620 - Separate presshell attachment and detachment in nsPresContext. r=heycam
This commit is contained in:
Родитель
64639661c1
Коммит
1764385b32
|
@ -335,7 +335,7 @@ nsPresContext::Destroy()
|
|||
nsPresContext::~nsPresContext()
|
||||
{
|
||||
NS_PRECONDITION(!mShell, "Presshell forgot to clear our mShell pointer");
|
||||
SetShell(nullptr);
|
||||
DetachShell();
|
||||
|
||||
Destroy();
|
||||
}
|
||||
|
@ -903,92 +903,101 @@ nsPresContext::Init(nsDeviceContext* aDeviceContext)
|
|||
// Note: We don't hold a reference on the shell; it has a reference to
|
||||
// us
|
||||
void
|
||||
nsPresContext::SetShell(nsIPresShell* aShell)
|
||||
nsPresContext::AttachShell(nsIPresShell* aShell)
|
||||
{
|
||||
MOZ_ASSERT(!mShell);
|
||||
mShell = aShell;
|
||||
|
||||
// Since CounterStyleManager is also the name of a method of
|
||||
// nsPresContext, it is necessary to prefix the class with the mozilla
|
||||
// namespace here.
|
||||
mCounterStyleManager = new mozilla::CounterStyleManager(this);
|
||||
|
||||
nsIDocument *doc = mShell->GetDocument();
|
||||
NS_ASSERTION(doc, "expect document here");
|
||||
if (doc) {
|
||||
// Have to update PresContext's mDocument before calling any other methods.
|
||||
mDocument = doc;
|
||||
}
|
||||
// Initialize our state from the user preferences, now that we
|
||||
// have a presshell, and hence a document.
|
||||
GetUserPreferences();
|
||||
|
||||
if (doc) {
|
||||
nsIURI *docURI = doc->GetDocumentURI();
|
||||
|
||||
if (IsDynamic() && docURI) {
|
||||
bool isChrome = false;
|
||||
bool isRes = false;
|
||||
docURI->SchemeIs("chrome", &isChrome);
|
||||
docURI->SchemeIs("resource", &isRes);
|
||||
|
||||
if (!isChrome && !isRes)
|
||||
mImageAnimationMode = mImageAnimationModePref;
|
||||
else
|
||||
mImageAnimationMode = imgIContainer::kNormalAnimMode;
|
||||
}
|
||||
|
||||
if (mLangService) {
|
||||
doc->AddCharSetObserver(this);
|
||||
UpdateCharSet(doc->GetDocumentCharacterSet());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsPresContext::DetachShell()
|
||||
{
|
||||
// Remove ourselves as the charset observer from the shell's doc, because
|
||||
// this shell may be going away for good.
|
||||
nsIDocument *doc = mShell ? mShell->GetDocument() : nullptr;
|
||||
if (doc) {
|
||||
doc->RemoveCharSetObserver(this);
|
||||
}
|
||||
|
||||
// The counter style manager's destructor needs to deallocate with the
|
||||
// presshell arena. Disconnect it before nulling out the shell.
|
||||
//
|
||||
// XXXbholley: Given recent refactorings, it probably makes more sense to
|
||||
// just null our mShell at the bottom of this function. I'm leaving it
|
||||
// this way to preserve the old ordering, but I doubt anything would break.
|
||||
if (mCounterStyleManager) {
|
||||
mCounterStyleManager->Disconnect();
|
||||
mCounterStyleManager = nullptr;
|
||||
}
|
||||
|
||||
if (mShell) {
|
||||
// Remove ourselves as the charset observer from the shell's doc, because
|
||||
// this shell may be going away for good.
|
||||
nsIDocument *doc = mShell->GetDocument();
|
||||
if (doc) {
|
||||
doc->RemoveCharSetObserver(this);
|
||||
}
|
||||
mShell = nullptr;
|
||||
|
||||
if (mEffectCompositor) {
|
||||
mEffectCompositor->Disconnect();
|
||||
mEffectCompositor = nullptr;
|
||||
}
|
||||
if (mTransitionManager) {
|
||||
mTransitionManager->Disconnect();
|
||||
mTransitionManager = nullptr;
|
||||
}
|
||||
if (mAnimationManager) {
|
||||
mAnimationManager->Disconnect();
|
||||
mAnimationManager = nullptr;
|
||||
}
|
||||
if (mRestyleManager) {
|
||||
mRestyleManager->Disconnect();
|
||||
mRestyleManager = nullptr;
|
||||
}
|
||||
if (mRefreshDriver && mRefreshDriver->PresContext() == this) {
|
||||
mRefreshDriver->Disconnect();
|
||||
// Can't null out the refresh driver here.
|
||||
}
|
||||
|
||||
mShell = aShell;
|
||||
if (IsRoot()) {
|
||||
nsRootPresContext* thisRoot = static_cast<nsRootPresContext*>(this);
|
||||
|
||||
if (mShell) {
|
||||
// Since CounterStyleManager is also the name of a method of
|
||||
// nsPresContext, it is necessary to prefix the class with the mozilla
|
||||
// namespace here.
|
||||
mCounterStyleManager = new mozilla::CounterStyleManager(this);
|
||||
// Have to cancel our plugin geometry timer, because the
|
||||
// callback for that depends on a non-null presshell.
|
||||
thisRoot->CancelApplyPluginGeometryTimer();
|
||||
|
||||
nsIDocument *doc = mShell->GetDocument();
|
||||
NS_ASSERTION(doc, "expect document here");
|
||||
if (doc) {
|
||||
// Have to update PresContext's mDocument before calling any other methods.
|
||||
mDocument = doc;
|
||||
}
|
||||
// Initialize our state from the user preferences, now that we
|
||||
// have a presshell, and hence a document.
|
||||
GetUserPreferences();
|
||||
|
||||
if (doc) {
|
||||
nsIURI *docURI = doc->GetDocumentURI();
|
||||
|
||||
if (IsDynamic() && docURI) {
|
||||
bool isChrome = false;
|
||||
bool isRes = false;
|
||||
docURI->SchemeIs("chrome", &isChrome);
|
||||
docURI->SchemeIs("resource", &isRes);
|
||||
|
||||
if (!isChrome && !isRes)
|
||||
mImageAnimationMode = mImageAnimationModePref;
|
||||
else
|
||||
mImageAnimationMode = imgIContainer::kNormalAnimMode;
|
||||
}
|
||||
|
||||
if (mLangService) {
|
||||
doc->AddCharSetObserver(this);
|
||||
UpdateCharSet(doc->GetDocumentCharacterSet());
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (mEffectCompositor) {
|
||||
mEffectCompositor->Disconnect();
|
||||
mEffectCompositor = nullptr;
|
||||
}
|
||||
if (mTransitionManager) {
|
||||
mTransitionManager->Disconnect();
|
||||
mTransitionManager = nullptr;
|
||||
}
|
||||
if (mAnimationManager) {
|
||||
mAnimationManager->Disconnect();
|
||||
mAnimationManager = nullptr;
|
||||
}
|
||||
if (mRestyleManager) {
|
||||
mRestyleManager->Disconnect();
|
||||
mRestyleManager = nullptr;
|
||||
}
|
||||
if (mRefreshDriver && mRefreshDriver->PresContext() == this) {
|
||||
mRefreshDriver->Disconnect();
|
||||
// Can't null out the refresh driver here.
|
||||
}
|
||||
|
||||
if (IsRoot()) {
|
||||
nsRootPresContext* thisRoot = static_cast<nsRootPresContext*>(this);
|
||||
|
||||
// Have to cancel our plugin geometry timer, because the
|
||||
// callback for that depends on a non-null presshell.
|
||||
thisRoot->CancelApplyPluginGeometryTimer();
|
||||
|
||||
// The did-paint timer also depends on a non-null pres shell.
|
||||
thisRoot->CancelDidPaintTimer();
|
||||
}
|
||||
// The did-paint timer also depends on a non-null pres shell.
|
||||
thisRoot->CancelDidPaintTimer();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -160,10 +160,11 @@ public:
|
|||
nsresult Init(nsDeviceContext* aDeviceContext);
|
||||
|
||||
/**
|
||||
* Set the presentation shell that this context is bound to.
|
||||
* Set and detach presentation shell that this context is bound to.
|
||||
* A presentation context may only be bound to a single shell.
|
||||
*/
|
||||
void SetShell(nsIPresShell* aShell);
|
||||
void AttachShell(nsIPresShell* aShell);
|
||||
void DetachShell();
|
||||
|
||||
|
||||
nsPresContextType Type() const { return mType; }
|
||||
|
|
|
@ -879,7 +879,7 @@ PresShell::Init(nsIDocument* aDocument,
|
|||
|
||||
// Bind the context to the presentation shell.
|
||||
mPresContext = aPresContext;
|
||||
aPresContext->SetShell(this);
|
||||
aPresContext->AttachShell(this);
|
||||
|
||||
// Now we can initialize the style set. Make sure to set the member before
|
||||
// calling Init, since various subroutines need to find the style set off
|
||||
|
@ -1241,12 +1241,12 @@ PresShell::Destroy()
|
|||
// (a) before mFrameArena's destructor runs so that our
|
||||
// mAllocatedPointers becomes empty and doesn't trip the assertion
|
||||
// in ~PresShell,
|
||||
// (b) before the mPresContext->SetShell(nullptr) below, so
|
||||
// (b) before the mPresContext->DetachShell() below, so
|
||||
// that when we clear the ArenaRefPtrs they'll still be able to
|
||||
// get back to this PresShell to deregister themselves (e.g. note
|
||||
// how nsStyleContext::Arena returns the PresShell got from its
|
||||
// rule node's nsPresContext, which would return null if we'd already
|
||||
// called mPresContext->SetShell(nullptr)), and
|
||||
// called mPresContext->DetachShell()), and
|
||||
// (c) before the mStyleSet->BeginShutdown() call just below, so that
|
||||
// the nsStyleContexts don't complain they're being destroyed later
|
||||
// than the rule tree is.
|
||||
|
@ -1304,7 +1304,7 @@ PresShell::Destroy()
|
|||
if (mPresContext) {
|
||||
// Clear out the prescontext's property table -- since our frame tree is
|
||||
// now dead, we shouldn't be looking up any more properties in that table.
|
||||
// We want to do this before we call SetShell() on the prescontext, so
|
||||
// We want to do this before we call DetachShell() on the prescontext, so
|
||||
// property destructors can usefully call GetPresShell() on the
|
||||
// prescontext.
|
||||
mPresContext->PropertyTable()->DeleteAll();
|
||||
|
@ -1323,7 +1323,7 @@ PresShell::Destroy()
|
|||
// 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 nullptr
|
||||
mPresContext->SetShell(nullptr);
|
||||
mPresContext->DetachShell();
|
||||
|
||||
// Clear the link handler (weak reference) as well
|
||||
mPresContext->SetLinkHandler(nullptr);
|
||||
|
|
Загрузка…
Ссылка в новой задаче