|
|
|
Lines 166-174
static NS_DEFINE_CID(kDOMScriptObjectFac
|
Link Here
|
|---|
|
| 166 |
|
166 |
|
| 167 |
#if defined(DEBUG_bryner) |
167 |
#if defined(DEBUG_bryner) |
| 168 |
//#define DEBUG_DOCSHELL_FOCUS |
168 |
//#define DEBUG_DOCSHELL_FOCUS |
|
|
169 |
#define DEBUG_PAGE_CACHE |
| 169 |
#endif |
170 |
#endif |
| 170 |
|
171 |
|
| 171 |
#include "plevent.h" |
172 |
#include "plevent.h" |
|
|
173 |
#include "nsGUIEvent.h" |
| 174 |
#include "nsIPrivateDOMEvent.h" |
| 175 |
#include "nsIDOMEventReceiver.h" |
| 176 |
#include "nsIEventListenerManager.h" |
| 177 |
#include "nsIPluginDocument.h" |
| 172 |
|
178 |
|
| 173 |
// Number of documents currently loading |
179 |
// Number of documents currently loading |
| 174 |
static PRInt32 gNumberOfDocumentsLoading = 0; |
180 |
static PRInt32 gNumberOfDocumentsLoading = 0; |
|
Lines 246-251
nsDocShell::nsDocShell():
|
Link Here
|
|---|
|
| 246 |
mIsBeingDestroyed(PR_FALSE), |
252 |
mIsBeingDestroyed(PR_FALSE), |
| 247 |
mIsExecutingOnLoadHandler(PR_FALSE), |
253 |
mIsExecutingOnLoadHandler(PR_FALSE), |
| 248 |
mIsPrintingOrPP(PR_FALSE), |
254 |
mIsPrintingOrPP(PR_FALSE), |
|
|
255 |
mSavingOldViewer(PR_FALSE), |
| 249 |
mAppType(nsIDocShell::APP_TYPE_UNKNOWN), |
256 |
mAppType(nsIDocShell::APP_TYPE_UNKNOWN), |
| 250 |
mChildOffset(0), |
257 |
mChildOffset(0), |
| 251 |
mBusyFlags(BUSY_FLAGS_NONE), |
258 |
mBusyFlags(BUSY_FLAGS_NONE), |
|
Lines 1355-1366
nsDocShell::SetCurrentURI(nsIURI *aURI,
|
Link Here
|
|---|
|
| 1355 |
isRoot = PR_TRUE; |
1362 |
isRoot = PR_TRUE; |
| 1356 |
} |
1363 |
} |
| 1357 |
if (mLSHE) { |
1364 |
if (mLSHE) { |
| 1358 |
nsCOMPtr<nsIHistoryEntry> historyEntry(do_QueryInterface(mLSHE)); |
1365 |
mLSHE->GetIsSubFrame(&isSubFrame); |
| 1359 |
|
|
|
| 1360 |
// Check if this is a subframe navigation |
| 1361 |
if (historyEntry) { |
| 1362 |
historyEntry->GetIsSubFrame(&isSubFrame); |
| 1363 |
} |
| 1364 |
} |
1366 |
} |
| 1365 |
|
1367 |
|
| 1366 |
if (!isSubFrame && !isRoot) { |
1368 |
if (!isSubFrame && !isRoot) { |
|
Lines 1675-1680
nsDocShell::TabToTreeOwner(PRBool aForwa
|
Link Here
|
|---|
|
| 1675 |
return NS_OK; |
1677 |
return NS_OK; |
| 1676 |
} |
1678 |
} |
| 1677 |
|
1679 |
|
|
|
1680 |
NS_IMETHODIMP |
| 1681 |
nsDocShell::GetSecurityUI(nsISecureBrowserUI **aSecurityUI) |
| 1682 |
{ |
| 1683 |
NS_IF_ADDREF(*aSecurityUI = mSecurityUI); |
| 1684 |
return NS_OK; |
| 1685 |
} |
| 1686 |
|
| 1687 |
NS_IMETHODIMP |
| 1688 |
nsDocShell::SetSecurityUI(nsISecureBrowserUI *aSecurityUI) |
| 1689 |
{ |
| 1690 |
mSecurityUI = aSecurityUI; |
| 1691 |
return NS_OK; |
| 1692 |
} |
| 1693 |
|
| 1678 |
//***************************************************************************** |
1694 |
//***************************************************************************** |
| 1679 |
// nsDocShell::nsIDocShellTreeItem |
1695 |
// nsDocShell::nsIDocShellTreeItem |
| 1680 |
//***************************************************************************** |
1696 |
//***************************************************************************** |
|
Lines 3257-3268
nsDocShell::LoadPage(nsISupports *aPageD
|
Link Here
|
|---|
|
| 3257 |
// load the page as view-source |
3273 |
// load the page as view-source |
| 3258 |
// |
3274 |
// |
| 3259 |
if (nsIWebPageDescriptor::DISPLAY_AS_SOURCE == aDisplayType) { |
3275 |
if (nsIWebPageDescriptor::DISPLAY_AS_SOURCE == aDisplayType) { |
| 3260 |
nsCOMPtr<nsIHistoryEntry> srcHE(do_QueryInterface(shEntry)); |
|
|
| 3261 |
nsCOMPtr<nsIURI> oldUri, newUri; |
3276 |
nsCOMPtr<nsIURI> oldUri, newUri; |
| 3262 |
nsCString spec, newSpec; |
3277 |
nsCString spec, newSpec; |
| 3263 |
|
3278 |
|
| 3264 |
// Create a new view-source URI and replace the original. |
3279 |
// Create a new view-source URI and replace the original. |
| 3265 |
rv = srcHE->GetURI(getter_AddRefs(oldUri)); |
3280 |
rv = shEntry->GetURI(getter_AddRefs(oldUri)); |
| 3266 |
if (NS_FAILED(rv)) |
3281 |
if (NS_FAILED(rv)) |
| 3267 |
return rv; |
3282 |
return rv; |
| 3268 |
|
3283 |
|
|
Lines 3716-3722
nsDocShell::SetTitle(const PRUnichar * a
|
Link Here
|
|---|
|
| 3716 |
// would suffice. |
3731 |
// would suffice. |
| 3717 |
if (mOSHE && (mLoadType != LOAD_BYPASS_HISTORY) && |
3732 |
if (mOSHE && (mLoadType != LOAD_BYPASS_HISTORY) && |
| 3718 |
(mLoadType != LOAD_HISTORY) && (mLoadType != LOAD_ERROR_PAGE)) { |
3733 |
(mLoadType != LOAD_HISTORY) && (mLoadType != LOAD_ERROR_PAGE)) { |
| 3719 |
mOSHE->SetTitle(mTitle.get()); |
3734 |
mOSHE->SetTitle(mTitle); |
| 3720 |
} |
3735 |
} |
| 3721 |
|
3736 |
|
| 3722 |
|
3737 |
|
|
Lines 4311-4317
nsDocShell::CancelRefreshURITimers()
|
Link Here
|
|---|
|
| 4311 |
return NS_OK; |
4326 |
return NS_OK; |
| 4312 |
} |
4327 |
} |
| 4313 |
|
4328 |
|
| 4314 |
NS_IMETHODIMP |
4329 |
void |
|
|
4330 |
nsDocShell::SuspendRefreshURIs() |
| 4331 |
{ |
| 4332 |
if (!mRefreshURIList) |
| 4333 |
return; |
| 4334 |
PRUint32 n = 0; |
| 4335 |
mRefreshURIList->Count(&n); |
| 4336 |
|
| 4337 |
nsCOMPtr<nsITimer> timer; |
| 4338 |
nsCOMPtr<nsITimerCallback> callback; |
| 4339 |
nsCOMPtr<nsRefreshTimer> rt; |
| 4340 |
|
| 4341 |
for (PRUint32 i = 0; i < n; ++i) { |
| 4342 |
timer = do_QueryElementAt(mRefreshURIList, i); |
| 4343 |
if (!timer) |
| 4344 |
continue; // this must be a nsRefreshURI already |
| 4345 |
|
| 4346 |
// Replace this timer object with a nsRefreshTimer object. |
| 4347 |
nsCOMPtr<nsITimerCallback> callback; |
| 4348 |
timer->GetCallback(getter_AddRefs(callback)); |
| 4349 |
|
| 4350 |
timer->Cancel(); |
| 4351 |
|
| 4352 |
nsCOMPtr<nsRefreshTimer> rt = do_QueryInterface(callback); |
| 4353 |
NS_ASSERTION(rt, "RefreshURIList timer callbacks should only be RefreshTimer objects"); |
| 4354 |
|
| 4355 |
mRefreshURIList->ReplaceElementAt(rt, i); |
| 4356 |
} |
| 4357 |
} |
| 4358 |
|
| 4359 |
nsresult |
| 4315 |
nsDocShell::RefreshURIFromQueue() |
4360 |
nsDocShell::RefreshURIFromQueue() |
| 4316 |
{ |
4361 |
{ |
| 4317 |
if (!mRefreshURIList) |
4362 |
if (!mRefreshURIList) |
|
Lines 4697-4702
nsDocShell::CreateAboutBlankContentViewe
|
Link Here
|
|---|
|
| 4697 |
return rv; |
4742 |
return rv; |
| 4698 |
} |
4743 |
} |
| 4699 |
|
4744 |
|
|
|
4745 |
PRBool |
| 4746 |
nsDocShell::CanSavePresentation(nsIRequest *aNewRequest) |
| 4747 |
{ |
| 4748 |
// If max_viewers is set to 0, don't ever try to save the presentation. |
| 4749 |
// This check should be removed once we've established that the |
| 4750 |
// immediate-evict case works correctly (see bug 274784). |
| 4751 |
PRInt32 maxViewers = 0; |
| 4752 |
mPrefs->GetIntPref("browser.sessionhistory.max_viewers", &maxViewers); |
| 4753 |
if (maxViewers == 0) |
| 4754 |
return PR_FALSE; |
| 4755 |
|
| 4756 |
// If the document is not done loading, don't cache it. |
| 4757 |
nsCOMPtr<nsPIDOMWindow> pWin = do_QueryInterface(mScriptGlobal); |
| 4758 |
if (!pWin || pWin->IsLoading()) |
| 4759 |
return PR_FALSE; |
| 4760 |
|
| 4761 |
// If there are any active requests in the document load group, don't cache |
| 4762 |
// the document. Ideally we would instead suspend these requests and |
| 4763 |
// resume them when restoring the presentation, but that is potentially |
| 4764 |
// difficult (e.g. XMLHttpRequest). |
| 4765 |
|
| 4766 |
nsCOMPtr<nsIDocument> doc = do_QueryInterface(pWin->GetExtantDocument()); |
| 4767 |
if (doc && doc->HasRequests(aNewRequest)) |
| 4768 |
return PR_FALSE; |
| 4769 |
|
| 4770 |
// Don't save plugin documents; we have no easy way of retrieving the |
| 4771 |
// plugin data after it is loaded. |
| 4772 |
nsCOMPtr<nsIPluginDocument> pluginDoc = do_QueryInterface(doc); |
| 4773 |
if (pluginDoc) |
| 4774 |
return PR_FALSE; |
| 4775 |
|
| 4776 |
// Only save presentation for "normal" loads and link loads. Anything else |
| 4777 |
// probably wants to refetch the page, so caching the old presentation |
| 4778 |
// would be incorrect. |
| 4779 |
if (mLoadType != LOAD_NORMAL && |
| 4780 |
mLoadType != LOAD_HISTORY && |
| 4781 |
mLoadType != LOAD_LINK) |
| 4782 |
return PR_FALSE; |
| 4783 |
|
| 4784 |
// If there is an unload or beforeunload listener on the window, then we do |
| 4785 |
// not save the presentation into the session history cache. |
| 4786 |
nsCOMPtr<nsIDOMEventReceiver> er = do_QueryInterface(mScriptGlobal); |
| 4787 |
if (er) { |
| 4788 |
nsCOMPtr<nsIEventListenerManager> eventManager; |
| 4789 |
er->GetListenerManager(getter_AddRefs(eventManager)); |
| 4790 |
|
| 4791 |
if (eventManager && eventManager->HasUnloadListeners()) |
| 4792 |
return PR_FALSE; |
| 4793 |
} |
| 4794 |
|
| 4795 |
// If the session history entry has the saveLayoutState flag set to false, |
| 4796 |
// then we should not cache the presentation. |
| 4797 |
|
| 4798 |
if (!mOSHE) |
| 4799 |
return PR_FALSE; // no entry to save into |
| 4800 |
|
| 4801 |
PRBool canSaveState; |
| 4802 |
mOSHE->GetSaveLayoutStateFlag(&canSaveState); |
| 4803 |
return canSaveState; |
| 4804 |
} |
| 4805 |
|
| 4806 |
nsresult |
| 4807 |
nsDocShell::CaptureState() |
| 4808 |
{ |
| 4809 |
nsCOMPtr<nsPIDOMWindow> privWin = do_QueryInterface(mScriptGlobal); |
| 4810 |
if (!privWin || !mOSHE) |
| 4811 |
return NS_ERROR_FAILURE; |
| 4812 |
|
| 4813 |
nsCOMPtr<nsISupports> windowState; |
| 4814 |
nsresult rv = privWin->SaveWindowState(getter_AddRefs(windowState)); |
| 4815 |
NS_ENSURE_SUCCESS(rv, rv); |
| 4816 |
|
| 4817 |
#ifdef DEBUG_PAGE_CACHE |
| 4818 |
nsCOMPtr<nsIURI> uri; |
| 4819 |
mOSHE->GetURI(getter_AddRefs(uri)); |
| 4820 |
nsCAutoString spec; |
| 4821 |
if (uri) |
| 4822 |
uri->GetSpec(spec); |
| 4823 |
printf("Saving presentation into session history\n"); |
| 4824 |
printf(" SH URI: %s\n", spec.get()); |
| 4825 |
#endif |
| 4826 |
|
| 4827 |
rv = mOSHE->SetWindowState(windowState); |
| 4828 |
NS_ENSURE_SUCCESS(rv, rv); |
| 4829 |
|
| 4830 |
// Suspend refresh URIs and save off the timer queue |
| 4831 |
SuspendRefreshURIs(); |
| 4832 |
rv = mOSHE->SetRefreshURIList(mRefreshURIList); |
| 4833 |
NS_ENSURE_SUCCESS(rv, rv); |
| 4834 |
|
| 4835 |
mRefreshURIList = nsnull; |
| 4836 |
|
| 4837 |
// Capture the current content viewer bounds. |
| 4838 |
nsCOMPtr<nsIPresShell> shell; |
| 4839 |
nsDocShell::GetPresShell(getter_AddRefs(shell)); |
| 4840 |
if (shell) { |
| 4841 |
nsIViewManager *vm = shell->GetViewManager(); |
| 4842 |
if (vm) { |
| 4843 |
nsIView *rootView = nsnull; |
| 4844 |
vm->GetRootView(rootView); |
| 4845 |
if (rootView) { |
| 4846 |
nsIWidget *widget = rootView->GetWidget(); |
| 4847 |
if (widget) { |
| 4848 |
nsRect bounds(0, 0, 0, 0); |
| 4849 |
widget->GetBounds(bounds); |
| 4850 |
rv = mOSHE->SetViewerBounds(bounds); |
| 4851 |
} |
| 4852 |
} |
| 4853 |
} |
| 4854 |
} |
| 4855 |
|
| 4856 |
// Capture the docshell hierarchy. |
| 4857 |
|
| 4858 |
PRInt32 childCount = mChildList.Count(); |
| 4859 |
nsCOMPtr<nsIDocShellTreeItem> childShell; |
| 4860 |
|
| 4861 |
mOSHE->ClearChildShells(); |
| 4862 |
|
| 4863 |
for (PRInt32 i = 0; i < childCount; ++i) { |
| 4864 |
childShell = do_QueryInterface(ChildAt(i)); |
| 4865 |
NS_ASSERTION(childShell, "null child shell"); |
| 4866 |
|
| 4867 |
mOSHE->AddChildShell(childShell); |
| 4868 |
} |
| 4869 |
|
| 4870 |
// Capture the security state. |
| 4871 |
nsCOMPtr<nsISecureBrowserUIState> securityState; |
| 4872 |
if (mSecurityUI) |
| 4873 |
mSecurityUI->CaptureState(getter_AddRefs(securityState)); |
| 4874 |
|
| 4875 |
return mOSHE->SetSecurityState(securityState); |
| 4876 |
} |
| 4877 |
|
| 4878 |
nsresult |
| 4879 |
nsDocShell::RestorePresentation(nsISHEntry *aSHEntry, PRBool aSavePresentation) |
| 4880 |
{ |
| 4881 |
NS_ASSERTION(mLoadType & LOAD_CMD_HISTORY, |
| 4882 |
"RestorePresentation should only be called for history loads"); |
| 4883 |
|
| 4884 |
nsCOMPtr<nsIURI> uri; |
| 4885 |
aSHEntry->GetURI(getter_AddRefs(uri)); |
| 4886 |
|
| 4887 |
nsCOMPtr<nsIContentViewer> viewer; |
| 4888 |
aSHEntry->GetContentViewer(getter_AddRefs(viewer)); |
| 4889 |
|
| 4890 |
#ifdef DEBUG_PAGE_CACHE |
| 4891 |
nsCAutoString spec; |
| 4892 |
if (uri) |
| 4893 |
uri->GetSpec(spec); |
| 4894 |
#endif |
| 4895 |
|
| 4896 |
if (!viewer) { |
| 4897 |
#ifdef DEBUG_PAGE_CACHE |
| 4898 |
printf("no saved presentation for uri: %s\n", spec.get()); |
| 4899 |
#endif |
| 4900 |
return NS_ERROR_NOT_AVAILABLE; |
| 4901 |
} |
| 4902 |
|
| 4903 |
NS_ASSERTION(mContentViewer != viewer, "Restoring existing presentation"); |
| 4904 |
|
| 4905 |
#ifdef DEBUG_PAGE_CACHE |
| 4906 |
printf("restoring presentation from session history: %s\n", spec.get()); |
| 4907 |
#endif |
| 4908 |
|
| 4909 |
// Save off the root view's parent and sibling so that we can insert the |
| 4910 |
// new content viewer's root view at the same position. Also save the |
| 4911 |
// bounds of the root view's widget. |
| 4912 |
|
| 4913 |
nsIView *rootViewSibling = nsnull, *rootViewParent = nsnull; |
| 4914 |
nsRect newBounds(0, 0, 0, 0); |
| 4915 |
|
| 4916 |
nsCOMPtr<nsIPresShell> oldPresShell; |
| 4917 |
nsDocShell::GetPresShell(getter_AddRefs(oldPresShell)); |
| 4918 |
if (oldPresShell) { |
| 4919 |
nsIViewManager *vm = oldPresShell->GetViewManager(); |
| 4920 |
if (vm) { |
| 4921 |
nsIView *oldRootView = nsnull; |
| 4922 |
vm->GetRootView(oldRootView); |
| 4923 |
|
| 4924 |
if (oldRootView) { |
| 4925 |
rootViewSibling = oldRootView->GetNextSibling(); |
| 4926 |
rootViewParent = oldRootView->GetParent(); |
| 4927 |
|
| 4928 |
nsIWidget *widget = oldRootView->GetWidget(); |
| 4929 |
if (widget) { |
| 4930 |
widget->GetBounds(newBounds); |
| 4931 |
} |
| 4932 |
} |
| 4933 |
} |
| 4934 |
} |
| 4935 |
|
| 4936 |
// Transfer ownership to mContentViewer. By ensuring that either the |
| 4937 |
// docshell or the session history, but not both, have references to the |
| 4938 |
// content viewer, we prevent the viewer from being torn down after |
| 4939 |
// Destroy() is called. |
| 4940 |
|
| 4941 |
if (!aSavePresentation) |
| 4942 |
FireUnloadNotification(); |
| 4943 |
|
| 4944 |
mFiredUnloadEvent = PR_FALSE; |
| 4945 |
|
| 4946 |
if (mContentViewer) { |
| 4947 |
mContentViewer->Close(); |
| 4948 |
|
| 4949 |
if (aSavePresentation) |
| 4950 |
mContentViewer->SetHistoryEntry(mOSHE); |
| 4951 |
|
| 4952 |
mContentViewer->Destroy(); |
| 4953 |
} |
| 4954 |
|
| 4955 |
mContentViewer.swap(viewer); |
| 4956 |
viewer = nsnull; // force a release to complete ownership transfer |
| 4957 |
|
| 4958 |
// Reattach to the window object. |
| 4959 |
nsresult rv = mContentViewer->Open(); |
| 4960 |
|
| 4961 |
// Now remove it from the cached presentation. |
| 4962 |
aSHEntry->SetContentViewer(nsnull); |
| 4963 |
|
| 4964 |
// Restore our child docshell hierarchy. |
| 4965 |
DestroyChildren(); |
| 4966 |
NS_ENSURE_SUCCESS(rv, rv); |
| 4967 |
|
| 4968 |
PRInt32 i = 0; |
| 4969 |
nsCOMPtr<nsIDocShellTreeItem> childShell; |
| 4970 |
while (NS_SUCCEEDED(aSHEntry->ChildShellAt(i++, |
| 4971 |
getter_AddRefs(childShell))) && |
| 4972 |
childShell) { |
| 4973 |
AddChild(childShell); |
| 4974 |
} |
| 4975 |
|
| 4976 |
// And release the references in the history entry. |
| 4977 |
aSHEntry->ClearChildShells(); |
| 4978 |
|
| 4979 |
// Restore the sticky state of the viewer. The viewer automatically |
| 4980 |
// sets itself as sticky in Destroy() to avoid teardown. |
| 4981 |
PRBool sticky; |
| 4982 |
aSHEntry->GetSticky(&sticky); |
| 4983 |
mContentViewer->SetSticky(sticky); |
| 4984 |
|
| 4985 |
// save the previous content viewer size |
| 4986 |
nsRect oldBounds(0, 0, 0, 0); |
| 4987 |
aSHEntry->GetViewerBounds(oldBounds); |
| 4988 |
|
| 4989 |
nsCOMPtr<nsIPresShell> shell; |
| 4990 |
nsDocShell::GetPresShell(getter_AddRefs(shell)); |
| 4991 |
|
| 4992 |
nsIViewManager *newVM = shell ? shell->GetViewManager() : nsnull; |
| 4993 |
nsIView *newRootView = nsnull; |
| 4994 |
if (newVM) |
| 4995 |
newVM->GetRootView(newRootView); |
| 4996 |
|
| 4997 |
// Insert the new root view at the correct location in the view tree. |
| 4998 |
if (rootViewParent) { |
| 4999 |
nsIViewManager *parentVM = rootViewParent->GetViewManager(); |
| 5000 |
|
| 5001 |
if (parentVM && newRootView) { |
| 5002 |
parentVM->InsertChild(rootViewParent, newRootView, |
| 5003 |
rootViewSibling, PR_TRUE); |
| 5004 |
|
| 5005 |
NS_ASSERTION(newRootView->GetNextSibling() == rootViewSibling, |
| 5006 |
"error in InsertChild"); |
| 5007 |
|
| 5008 |
shell->InvalidateViewManagers(); |
| 5009 |
} |
| 5010 |
} |
| 5011 |
|
| 5012 |
// restore the state of the window object |
| 5013 |
nsCOMPtr<nsPIDOMWindow> privWin = |
| 5014 |
do_GetInterface(NS_STATIC_CAST(nsIInterfaceRequestor*, this)); |
| 5015 |
NS_ASSERTION(privWin, "could not get nsPIDOMWindow interface"); |
| 5016 |
|
| 5017 |
nsCOMPtr<nsISupports> windowState; |
| 5018 |
aSHEntry->GetWindowState(getter_AddRefs(windowState)); |
| 5019 |
|
| 5020 |
rv = privWin->RestoreWindowState(windowState); |
| 5021 |
NS_ENSURE_SUCCESS(rv, rv); |
| 5022 |
|
| 5023 |
aSHEntry->SetWindowState(nsnull); |
| 5024 |
|
| 5025 |
// Restore the refresh URI list. |
| 5026 |
aSHEntry->GetRefreshURIList(getter_AddRefs(mRefreshURIList)); |
| 5027 |
aSHEntry->SetRefreshURIList(nsnull); |
| 5028 |
|
| 5029 |
mOSHE = aSHEntry; |
| 5030 |
|
| 5031 |
// mEODForCurrentDocument is true here, so EndPageLoad will not fire |
| 5032 |
// onload (we fire that below, in a special way so that the content window |
| 5033 |
// does not see it). |
| 5034 |
EndPageLoad(nsnull, nsnull, NS_OK); |
| 5035 |
|
| 5036 |
nsCOMPtr<nsISHistory> rootSH; |
| 5037 |
GetRootSessionHistory(getter_AddRefs(rootSH)); |
| 5038 |
if (rootSH) { |
| 5039 |
nsCOMPtr<nsISHistoryInternal> hist = do_QueryInterface(rootSH); |
| 5040 |
hist->UpdateIndex(); |
| 5041 |
} |
| 5042 |
|
| 5043 |
// Make sure this presentation is the same size as the previous |
| 5044 |
// presentation. If this is not the same size we showed it at last time, |
| 5045 |
// then we need to resize the widget. |
| 5046 |
|
| 5047 |
// XXXbryner This interacts poorly with Firefox's infobar. If the old |
| 5048 |
// presentation had the infobar visible, then we will resize the new |
| 5049 |
// presentation to that smaller size. However, firing the locationchanged |
| 5050 |
// event will hide the infobar, which will immediately resize the window |
| 5051 |
// back to the larger size. A future optimization might be to restore |
| 5052 |
// the presentation at the "wrong" size, then fire the locationchanged |
| 5053 |
// event and check whether the docshell's new size is the same as the |
| 5054 |
// cached viewer size (skipping the resize if they are equal). |
| 5055 |
|
| 5056 |
if (newRootView) { |
| 5057 |
nsIWidget *widget = newRootView->GetWidget(); |
| 5058 |
if (widget && !newBounds.IsEmpty() && newBounds != oldBounds) { |
| 5059 |
#ifdef DEBUG_PAGE_CACHE |
| 5060 |
printf("resize widget(%d, %d, %d, %d)\n", newBounds.x, |
| 5061 |
newBounds.y, newBounds.width, newBounds.height); |
| 5062 |
#endif |
| 5063 |
|
| 5064 |
widget->Resize(newBounds.x, newBounds.y, newBounds.width, |
| 5065 |
newBounds.height, PR_FALSE); |
| 5066 |
} |
| 5067 |
} |
| 5068 |
|
| 5069 |
// Reset the security state |
| 5070 |
if (mSecurityUI) { |
| 5071 |
nsCOMPtr<nsISecureBrowserUIState> securityState; |
| 5072 |
aSHEntry->GetSecurityState(getter_AddRefs(securityState)); |
| 5073 |
if (securityState) |
| 5074 |
mSecurityUI->TransitionToState(securityState); |
| 5075 |
} |
| 5076 |
|
| 5077 |
SetCurrentURI(uri); |
| 5078 |
|
| 5079 |
// Dispatch events. This is a little messy. We need to avoid firing |
| 5080 |
// onload so that it is visible from the content DOM window, but we _do_ |
| 5081 |
// want the chrome to see it for chrome/extensions that look for page load. |
| 5082 |
// In addition, we need to fire DOMPageRestore on the content window. |
| 5083 |
|
| 5084 |
if (shell) { |
| 5085 |
nsEvent event(PR_TRUE, NS_PAGE_LOAD); |
| 5086 |
nsEventStatus status = nsEventStatus_eIgnore; |
| 5087 |
|
| 5088 |
nsCOMPtr<nsIChromeEventHandler> handler = |
| 5089 |
privWin->GetChromeEventHandler(); |
| 5090 |
|
| 5091 |
PRUint32 flags = NS_EVENT_FLAG_INIT; |
| 5092 |
event.flags |= flags; |
| 5093 |
flags &= ~(NS_EVENT_FLAG_CANT_BUBBLE | NS_EVENT_FLAG_CANT_CANCEL); |
| 5094 |
flags |= NS_EVENT_FLAG_BUBBLE | NS_EVENT_FLAG_CAPTURE; |
| 5095 |
|
| 5096 |
nsIDOMEvent *domEvt = nsnull; |
| 5097 |
nsPresContext *pc = shell->GetPresContext(); |
| 5098 |
|
| 5099 |
rv = handler->HandleChromeEvent(pc, &event, &domEvt, |
| 5100 |
flags & NS_EVENT_CAPTURE_MASK, |
| 5101 |
&status); |
| 5102 |
NS_ENSURE_SUCCESS(rv, rv); |
| 5103 |
|
| 5104 |
if (domEvt) { |
| 5105 |
nsrefcnt rc; |
| 5106 |
NS_RELEASE2(domEvt, rc); |
| 5107 |
if (0 != rc) { |
| 5108 |
// Okay, so someone in the DOM loop (a listener, JS object) |
| 5109 |
// still has a ref to the DOM Event but the internal data |
| 5110 |
// hasn't been malloc'd. Force a copy of the data here so the |
| 5111 |
// DOM Event is still valid. |
| 5112 |
|
| 5113 |
nsCOMPtr<nsIPrivateDOMEvent> privateEvent = |
| 5114 |
do_QueryInterface(domEvt); |
| 5115 |
|
| 5116 |
if (privateEvent) { |
| 5117 |
privateEvent->DuplicatePrivateData(); |
| 5118 |
} |
| 5119 |
} |
| 5120 |
} |
| 5121 |
|
| 5122 |
status = nsEventStatus_eIgnore; |
| 5123 |
nsEvent restoreEvent(PR_TRUE, NS_PAGE_RESTORE); |
| 5124 |
|
| 5125 |
mScriptGlobal->HandleDOMEvent(pc, &restoreEvent, nsnull, |
| 5126 |
NS_EVENT_FLAG_INIT, &status); |
| 5127 |
} |
| 5128 |
|
| 5129 |
rv = mContentViewer->Show(); |
| 5130 |
NS_ENSURE_SUCCESS(rv, rv); |
| 5131 |
|
| 5132 |
// Restart plugins |
| 5133 |
if (shell) |
| 5134 |
shell->Thaw(); |
| 5135 |
|
| 5136 |
// XXXbryner Making this invalidate synchronous causes unpainted areas |
| 5137 |
// (on Mac, at least) if the above locationchanged event hides Firefox's |
| 5138 |
// infobar. Doing it asynchronously seems to work around the problem, but |
| 5139 |
// shouldn't the style change that hides the infobar handle all necessary |
| 5140 |
// invalidation, including the newly-exposed area? |
| 5141 |
|
| 5142 |
return mParentWidget->Invalidate(PR_FALSE); |
| 5143 |
} |
| 5144 |
|
| 4700 |
NS_IMETHODIMP |
5145 |
NS_IMETHODIMP |
| 4701 |
nsDocShell::CreateContentViewer(const char *aContentType, |
5146 |
nsDocShell::CreateContentViewer(const char *aContentType, |
| 4702 |
nsIRequest * request, |
5147 |
nsIRequest * request, |
|
Lines 4723-4729
nsDocShell::CreateContentViewer(const ch
|
Link Here
|
|---|
|
| 4723 |
// is changed within the DocShell - otherwise, javascript will get the |
5168 |
// is changed within the DocShell - otherwise, javascript will get the |
| 4724 |
// wrong information :-( |
5169 |
// wrong information :-( |
| 4725 |
// |
5170 |
// |
| 4726 |
(void) FireUnloadNotification(); |
5171 |
|
|
|
5172 |
PRBool savePresentation = CanSavePresentation(request); |
| 5173 |
if (!savePresentation) |
| 5174 |
FireUnloadNotification(); |
| 4727 |
|
5175 |
|
| 4728 |
// Set mFiredUnloadEvent = PR_FALSE so that the unload handler for the |
5176 |
// Set mFiredUnloadEvent = PR_FALSE so that the unload handler for the |
| 4729 |
// *new* document will fire. |
5177 |
// *new* document will fire. |
|
Lines 4738-4743
nsDocShell::CreateContentViewer(const ch
|
Link Here
|
|---|
|
| 4738 |
|
5186 |
|
| 4739 |
PRBool onLocationChangeNeeded = OnLoadingSite(aOpenedChannel, PR_FALSE); |
5187 |
PRBool onLocationChangeNeeded = OnLoadingSite(aOpenedChannel, PR_FALSE); |
| 4740 |
|
5188 |
|
|
|
5189 |
if (savePresentation) { |
| 5190 |
// The old content viewer will be saved during the call to Embed(). |
| 5191 |
rv = CaptureState(); |
| 5192 |
if (NS_SUCCEEDED(rv)) |
| 5193 |
mSavingOldViewer = PR_TRUE; |
| 5194 |
// XXX this isn't really fatal, necessarily... |
| 5195 |
// should we try to fire unload if NS_FAILED(rv) ? |
| 5196 |
} |
| 5197 |
|
| 4741 |
// let's try resetting the load group if we need to... |
5198 |
// let's try resetting the load group if we need to... |
| 4742 |
nsCOMPtr<nsILoadGroup> currentLoadGroup; |
5199 |
nsCOMPtr<nsILoadGroup> currentLoadGroup; |
| 4743 |
NS_ENSURE_SUCCESS(aOpenedChannel-> |
5200 |
NS_ENSURE_SUCCESS(aOpenedChannel-> |
|
Lines 4779-4784
nsDocShell::CreateContentViewer(const ch
|
Link Here
|
|---|
|
| 4779 |
NS_ENSURE_SUCCESS(Embed(viewer, "", (nsISupports *) nsnull), |
5236 |
NS_ENSURE_SUCCESS(Embed(viewer, "", (nsISupports *) nsnull), |
| 4780 |
NS_ERROR_FAILURE); |
5237 |
NS_ERROR_FAILURE); |
| 4781 |
|
5238 |
|
|
|
5239 |
mSavingOldViewer = PR_FALSE; |
| 4782 |
mEODForCurrentDocument = PR_FALSE; |
5240 |
mEODForCurrentDocument = PR_FALSE; |
| 4783 |
|
5241 |
|
| 4784 |
// if this document is part of a multipart document, |
5242 |
// if this document is part of a multipart document, |
|
Lines 5028-5033
nsDocShell::SetupNewViewer(nsIContentVie
|
Link Here
|
|---|
|
| 5028 |
|
5486 |
|
| 5029 |
mContentViewer->Close(); |
5487 |
mContentViewer->Close(); |
| 5030 |
aNewViewer->SetPreviousViewer(mContentViewer); |
5488 |
aNewViewer->SetPreviousViewer(mContentViewer); |
|
|
5489 |
|
| 5490 |
if (mSavingOldViewer) { |
| 5491 |
// Tell the old content viewer to hibernate in session history when |
| 5492 |
// it is destroyed. |
| 5493 |
mContentViewer->SetHistoryEntry(mOSHE); |
| 5494 |
} |
| 5495 |
|
| 5031 |
mContentViewer = nsnull; |
5496 |
mContentViewer = nsnull; |
| 5032 |
} |
5497 |
} |
| 5033 |
|
5498 |
|
|
Lines 5568-5574
nsDocShell::InternalLoad(nsIURI * aURI,
|
Link Here
|
|---|
|
| 5568 |
NS_ENSURE_TRUE(hEntry, NS_ERROR_FAILURE); |
6033 |
NS_ENSURE_TRUE(hEntry, NS_ERROR_FAILURE); |
| 5569 |
nsCOMPtr<nsISHEntry> shEntry(do_QueryInterface(hEntry)); |
6034 |
nsCOMPtr<nsISHEntry> shEntry(do_QueryInterface(hEntry)); |
| 5570 |
if (shEntry) |
6035 |
if (shEntry) |
| 5571 |
shEntry->SetTitle(mTitle.get()); |
6036 |
shEntry->SetTitle(mTitle); |
| 5572 |
} |
6037 |
} |
| 5573 |
|
6038 |
|
| 5574 |
return NS_OK; |
6039 |
return NS_OK; |
|
Lines 5588-5593
nsDocShell::InternalLoad(nsIURI * aURI,
|
Link Here
|
|---|
|
| 5588 |
} |
6053 |
} |
| 5589 |
} |
6054 |
} |
| 5590 |
|
6055 |
|
|
|
6056 |
// Check for saving the presentation here, before calling Stop(). |
| 6057 |
// This is necessary so that we can catch any pending requests. |
| 6058 |
PRBool savePresentation = |
| 6059 |
aSHEntry ? CanSavePresentation(nsnull) : PR_FALSE; |
| 6060 |
|
| 5591 |
// Don't stop current network activity for javascript: URL's since |
6061 |
// Don't stop current network activity for javascript: URL's since |
| 5592 |
// they might not result in any data, and thus nothing should be |
6062 |
// they might not result in any data, and thus nothing should be |
| 5593 |
// stopped in those cases. In the case where they do result in |
6063 |
// stopped in those cases. In the case where they do result in |
|
Lines 5623-5628
nsDocShell::InternalLoad(nsIURI * aURI,
|
Link Here
|
|---|
|
| 5623 |
// been called. |
6093 |
// been called. |
| 5624 |
mLSHE = aSHEntry; |
6094 |
mLSHE = aSHEntry; |
| 5625 |
|
6095 |
|
|
|
6096 |
// If we have a saved content viewer in history, restore and show it now. |
| 6097 |
if (aSHEntry) { |
| 6098 |
if (!savePresentation) |
| 6099 |
FireUnloadNotification(); |
| 6100 |
|
| 6101 |
mFiredUnloadEvent = PR_FALSE; |
| 6102 |
|
| 6103 |
if (savePresentation) |
| 6104 |
rv = CaptureState(); |
| 6105 |
|
| 6106 |
rv = RestorePresentation(aSHEntry, savePresentation && |
| 6107 |
NS_SUCCEEDED(rv)); |
| 6108 |
if (NS_SUCCEEDED(rv)) |
| 6109 |
return rv; |
| 6110 |
} |
| 6111 |
|
| 5626 |
nsCOMPtr<nsIRequest> req; |
6112 |
nsCOMPtr<nsIRequest> req; |
| 5627 |
rv = DoURILoad(aURI, aReferrer, |
6113 |
rv = DoURILoad(aURI, aReferrer, |
| 5628 |
!(aFlags & INTERNAL_LOAD_FLAGS_DONT_SEND_REFERRER), |
6114 |
!(aFlags & INTERNAL_LOAD_FLAGS_DONT_SEND_REFERRER), |
|
Lines 6520-6531
nsDocShell::AddToSessionHistory(nsIURI *
|
Link Here
|
|---|
|
| 6520 |
} |
7006 |
} |
| 6521 |
|
7007 |
|
| 6522 |
//Title is set in nsDocShell::SetTitle() |
7008 |
//Title is set in nsDocShell::SetTitle() |
| 6523 |
entry->Create(aURI, // uri |
7009 |
entry->Create(aURI, // uri |
| 6524 |
nsnull, // Title |
7010 |
EmptyString(), // Title |
| 6525 |
nsnull, // DOMDocument |
7011 |
inputStream, // Post data stream |
| 6526 |
inputStream, // Post data stream |
7012 |
nsnull, // LayoutHistory state |
| 6527 |
nsnull, // LayoutHistory state |
7013 |
cacheKey, // CacheKey |
| 6528 |
cacheKey, // CacheKey |
|
|
| 6529 |
mContentTypeHint); // Content-type |
7014 |
mContentTypeHint); // Content-type |
| 6530 |
entry->SetReferrerURI(referrerURI); |
7015 |
entry->SetReferrerURI(referrerURI); |
| 6531 |
/* If cache got a 'no-store', ask SH not to store |
7016 |
/* If cache got a 'no-store', ask SH not to store |
|
Lines 6556-6562
nsDocShell::AddToSessionHistory(nsIURI *
|
Link Here
|
|---|
|
| 6556 |
if (LOAD_TYPE_HAS_FLAGS(mLoadType, LOAD_FLAGS_REPLACE_HISTORY)) { |
7041 |
if (LOAD_TYPE_HAS_FLAGS(mLoadType, LOAD_FLAGS_REPLACE_HISTORY)) { |
| 6557 |
// Replace current entry in session history. |
7042 |
// Replace current entry in session history. |
| 6558 |
PRInt32 index = 0; |
7043 |
PRInt32 index = 0; |
| 6559 |
nsCOMPtr<nsIHistoryEntry> hEntry; |
|
|
| 6560 |
mSessionHistory->GetIndex(&index); |
7044 |
mSessionHistory->GetIndex(&index); |
| 6561 |
nsCOMPtr<nsISHistoryInternal> shPrivate(do_QueryInterface(mSessionHistory)); |
7045 |
nsCOMPtr<nsISHistoryInternal> shPrivate(do_QueryInterface(mSessionHistory)); |
| 6562 |
// Replace the current entry with the new entry |
7046 |
// Replace the current entry with the new entry |
|
Lines 6601-6610
nsDocShell::LoadHistoryEntry(nsISHEntry
|
Link Here
|
|---|
|
| 6601 |
nsCAutoString contentType; |
7085 |
nsCAutoString contentType; |
| 6602 |
|
7086 |
|
| 6603 |
NS_ENSURE_TRUE(aEntry, NS_ERROR_FAILURE); |
7087 |
NS_ENSURE_TRUE(aEntry, NS_ERROR_FAILURE); |
| 6604 |
nsCOMPtr<nsIHistoryEntry> hEntry(do_QueryInterface(aEntry)); |
|
|
| 6605 |
NS_ENSURE_TRUE(hEntry, NS_ERROR_FAILURE); |
| 6606 |
|
7088 |
|
| 6607 |
NS_ENSURE_SUCCESS(hEntry->GetURI(getter_AddRefs(uri)), NS_ERROR_FAILURE); |
7089 |
NS_ENSURE_SUCCESS(aEntry->GetURI(getter_AddRefs(uri)), NS_ERROR_FAILURE); |
| 6608 |
NS_ENSURE_SUCCESS(aEntry->GetReferrerURI(getter_AddRefs(referrerURI)), |
7090 |
NS_ENSURE_SUCCESS(aEntry->GetReferrerURI(getter_AddRefs(referrerURI)), |
| 6609 |
NS_ERROR_FAILURE); |
7091 |
NS_ERROR_FAILURE); |
| 6610 |
NS_ENSURE_SUCCESS(aEntry->GetPostData(getter_AddRefs(postData)), |
7092 |
NS_ENSURE_SUCCESS(aEntry->GetPostData(getter_AddRefs(postData)), |
|
Lines 6699-6707
nsDocShell::CloneAndReplace(nsISHEntry *
|
Link Here
|
|---|
|
| 6699 |
nsISHEntry *dest = (nsISHEntry *) nsnull; |
7181 |
nsISHEntry *dest = (nsISHEntry *) nsnull; |
| 6700 |
PRUint32 srcID; |
7182 |
PRUint32 srcID; |
| 6701 |
src->GetID(&srcID); |
7183 |
src->GetID(&srcID); |
| 6702 |
nsCOMPtr<nsIHistoryEntry> srcHE(do_QueryInterface(src)); |
|
|
| 6703 |
|
7184 |
|
| 6704 |
if (!src || !replaceEntry || !srcHE) |
7185 |
if (!src || !replaceEntry) |
| 6705 |
return NS_ERROR_FAILURE; |
7186 |
return NS_ERROR_FAILURE; |
| 6706 |
|
7187 |
|
| 6707 |
if (srcID == aCloneID) { |
7188 |
if (srcID == aCloneID) { |