/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
nsSHEntryShared::~nsSHEntryShared() { // The destruction can be caused by either the entry is removed from session // history and no one holds the reference, or the whole session history is on // destruction. We want to ensure that we invoke // shistory->RemoveFromExpirationTracker for the former case.
RemoveFromExpirationTracker();
// Calling RemoveDynEntriesForBFCacheEntry on destruction is unnecessary since // there couldn't be any SHEntry holding this shared entry, and we noticed // that calling RemoveDynEntriesForBFCacheEntry in the middle of // nsSHistory::Release can cause a crash, so set mSHistory to null explicitly // before RemoveFromBFCacheSync.
mSHistory = nullptr; if (mDocumentViewer) {
RemoveFromBFCacheSync();
}
}
void nsSHEntryShared::SyncPresentationState() { if (mDocumentViewer && mWindowState) { // If we have a content viewer and a window state, we should be ok. return;
}
if (mDocumentViewer || !aViewer) {
DropPresentationState();
}
// If we're setting mDocumentViewer to null, state should already be cleared // in the DropPresentationState() call above; If we're setting it to a // non-null content viewer, the entry shouldn't have been tracked either.
MOZ_ASSERT(!GetExpirationState()->IsTracked());
mDocumentViewer = aViewer;
if (mDocumentViewer) { // mSHistory is only set for root entries, but in general bfcache only // applies to root entries as well. BFCache for subframe navigation has been // disabled since 2005 in bug 304860. if (nsCOMPtr<nsISHistory> shistory = do_QueryReferent(mSHistory)) {
shistory->AddToExpirationTracker(this);
}
// Store observed document in strong pointer in case it is removed from // the documentviewer
mDocument = mDocumentViewer->GetDocument(); if (mDocument) {
mDocument->SetBFCacheEntry(this);
mDocument->AddMutationObserver(this);
}
}
return NS_OK;
}
nsresult nsSHEntryShared::RemoveFromBFCacheSync() {
MOZ_ASSERT(mDocumentViewer && mDocument, "we're not in the bfcache!");
// The call to DropPresentationState could drop the last reference, so hold // |this| until RemoveDynEntriesForBFCacheEntry finishes.
RefPtr<nsSHEntryShared> kungFuDeathGrip = this;
// DropPresentationState would clear mDocumentViewer.
nsCOMPtr<nsIDocumentViewer> viewer = mDocumentViewer;
DropPresentationState();
if (viewer) {
viewer->Destroy();
}
// Now that we've dropped the viewer, we have to clear associated dynamic // subframe entries.
nsCOMPtr<nsISHistory> shistory = do_QueryReferent(mSHistory); if (shistory) {
shistory->RemoveDynEntriesForBFCacheEntry(this);
}
return NS_OK;
}
nsresult nsSHEntryShared::RemoveFromBFCacheAsync() {
MOZ_ASSERT(mDocumentViewer && mDocument, "we're not in the bfcache!");
// Check it again to play safe in release builds. if (!mDocument) { return NS_ERROR_UNEXPECTED;
}
// DropPresentationState would clear mDocumentViewer & mDocument. Capture and // release the references asynchronously so that the document doesn't get // nuked mid-mutation.
nsCOMPtr<nsIDocumentViewer> viewer = mDocumentViewer;
RefPtr<dom::Document> document = mDocument;
RefPtr<nsSHEntryShared> self = this;
nsresult rv = mDocument->Dispatch(NS_NewRunnableFunction( "nsSHEntryShared::RemoveFromBFCacheAsync", [self, viewer, document]() { if (viewer) {
viewer->Destroy();
}
nsCOMPtr<nsISHistory> shistory = do_QueryReferent(self->mSHistory); if (shistory) {
shistory->RemoveDynEntriesForBFCacheEntry(self);
}
}));
if (NS_FAILED(rv)) {
NS_WARNING("Failed to dispatch RemoveFromBFCacheAsync runnable.");
} else { // Drop presentation. Only do this if we succeeded in posting the event // since otherwise the document could be torn down mid-mutation, causing // crashes.
DropPresentationState();
}
return NS_OK;
}
// Don't evict a page from bfcache for attribute mutations on NAC subtrees like // scrollbars. staticbool IgnoreMutationForBfCache(const nsINode& aNode) { for (const nsINode* node = &aNode; node; node = node->GetParentNode()) { if (!node->ChromeOnlyAccess()) { break;
} // Make sure we find a scrollbar in the ancestor chain, to be safe. if (node->IsXULElement(nsGkAtoms::scrollbar)) { returntrue;
}
} returnfalse;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.